A efficiency comparison between while for generator comprehension - Python while、for、生成器、列表推导等语句的执行效率对比

python中,同一个功能的实现,可以用多种语句来实现,比如说:while语句、for语句、生成器、列表推导、内置函数等实现,然而他们的效率并不一样。这里有一个小程序来测试它们执行的效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import sys  
nums = 100

#每个函数实现的都是从1-100的自然数的绝对值添加进一个list

def while_Statement(): #while loop实现
res = []
x = 0
while nums > x:
x += 1
res.append(abs(x))

def for_Statement(): #for loop实现
res = []
for x in range(nums):
res.append(abs(x))

def generator_Expression(): #生成器实现
res = list(abs(x) for x in range(nums))

def list_Comprehension(): #列表解析式实现,对比生成器实现可以发现两者区别只有中括号与小括号
res = [abs(x) for x in range(nums)]


def map_Function(): #map函数(内置函数)实现
res = map(abs, range(nums))

if __name__=='__main__':
import timeit #用timeit模块来测试
print sys.version
funcs = [while_Statement, for_Statement, generator_Expression, list_Comprehension, map_Function]
for func in funcs:
print func.__name__.ljust(20),': ',timeit.timeit("func()", setup="from __main__ import func")
测试结果:

>>>
2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)]
while_Statement : 16.0008671284
for_Statement : 12.9374330044
generator_Expression : 10.133701086
list_Comprehension : 7.86516404152
map_Function : 5.24277615547

以上用timeit模块两种测试方式测试了若干组数字,得出的结果是执行内置函数最快,其次就是列表推导,再其次生成器和for循环,while循环最慢。最快的使用内置函数的方法要比使用最慢的while快两倍以上。

简单分析下原因:

  • 内置函数比如说map,filter,reduce基本上都是用C语言来实现的,所以速度是最快的,
  • 列表推导内的迭代在解释器内是以C语言的速度运行的(一般是for循环的两倍,对大型文件操作而言
  • 列表推导效果尤其明显),相比较for循环代码是在PVM步进运行要快的多
  • for循环里面含range(),相对速度也会快些,
  • while语句是纯粹用Python代码写成,所以速度最慢。

综上,所以函数式编程最好使用内置函数,然后才考虑使用列表推导或for循环。最好不用while循环。

##参考资料

  1. Python while、for、生成器、列表推导等语句的执行效率测试
  2. PythonSpeed/PerformanceTips
  3. Python 性能小贴士 (第1部分)