Python是个好东西,但奈何时间不够用啊,路上坐地铁也未必有座儿,于是乎站着写代码的不只有那些比较潮流的办公室有,我也是其中一员,不过我是在运动过程中写代码,需要两脚站稳保持中立姿态,同时还要注意不能妨碍他人,嗯,总之是技术活儿,谁让咱是技术人员呢。扯完废话,把今天在路上写的一个Python小文件贴出来,用来对比Python下各种迭代方法的耗时。因为比较简单,所以直接贴出timerseqs.py文件的代码:
#!usrr/bin/env python
#file timerseqs.py
import time, sys
reps=1000
size=10000
def tester(func,*args):
startTime=time.time()
for i in range(reps):
func(*args)
elapsed=time.time()-startTime
return elapsed
#end def
def forStatement():
res=[]
for x in range(size):
res.append(abs(x))
#end def
def listComprehension():
res=[abs(x) for x in range(size)]
#end def
def mapFunction():
res=map(abs,range(size))
#end def
def generatorExpression():
res=list(abs(x) for x in range(size))
#end def
print sys.version
tests=(forStatement,listComprehension,mapFunction,generatorExpression)
for testFunc in tests:
print testFunc.__name__.ljust(20),'=>',tester(testFunc)
那么测试的结果如下图所示:
这个脚本测试了所有构造结果列表可能的方法,每一个都依次执行了一千万步,也就是说,这四个测试分别创建了一千次结果列表,每个列表中又含有一万个元素。在我的平板电脑上测试的结果,跟我在学习手册上看到的略有出入,但是差距不是太离谱,运行结果显示:列表解析大概比for循环语句快两倍,而map在映射像abs这样儿的内置函数时比列表解析要稍微快一些。
但是,当我们改变这段代码的时候呢?如果我们在每个迭代中执行一个真正的操作,例如,我们将代码做如下改动,在迭代中添加一个加法运算:
#!usrr/bin/env python
#file timerseqs.py
import time, sys
reps=1000
size=10000
def tester(func,*args):
startTime=time.time()
for i in range(reps):
func(*args)
elapsed=time.time()-startTime
return elapsed
#end def
def forStatement():
res=[]
for x in range(size):
res.append(x+10)
#end def
def listComprehension():
res=[x+10 for x in range(size)]
#end def
def mapFunction():
res=map(lambda x:x+10,range(size))
#end def
def generatorExpression():
res=list(x+10 for x in range(size))
#end def
print sys.version
tests=(forStatement,listComprehension,mapFunction,generatorExpression)
for testFunc in tests:
print testFunc.__name__.ljust(20),'=>',tester(testFunc)
那么,我们再来执行一下看下效果:
此时,map反而变得更慢,尽管可能for循环语句中代码更多了。
从这个脚本中,我们对Python代码的性能分析也有了初步的一个了解,因为Python的解释器的优化是相当内在的,所以我们很难猜测出哪一种方法的性能是最佳的,但我们所能做到的就是使用Python,计算代码的运行时间。在这种情况下,我们所能确定的就是,对于目前的Python,map调用中使用用户定义的函数至少会导致map慢两倍以上,而列表解析对这样儿的运算处理最快。
同时还有一点,就是我们在编写Python代码的时候,性能未必就是最优先考虑的,首先要为可读性和简洁性的标准而努力,如果有必要的话,之后再进行优化。
2013年05月03日,Eric.Tang 记