朋友们,如需转载请标明出处:https://blog.csdn.net/jiangjunshow
声明:在人工智能技术教学期间,不少学生向我提一些python相关的问题,所以为了让同学们掌握更多扩展知识更好地理解AI技术,我让助理负责分享这套python系列教程,希望能帮到大家!由于这套python教程不是由我所写,所以不如我的AI技术教学风趣幽默,学起来比较枯燥;但它的知识点还是讲到位的了,也值得阅读!想要学习AI技术的同学可以点击跳转到我的教学网站。PS:看不懂本篇文章的同学请先看前面的文章,循序渐进每天学一点就不会觉得难了!
我们已经学习了多种迭代工具方法,那么哪一种工具最快呢?
列表解析要比for循环语句有速度方面的性能优势,m a p会依据调用方法的不同表现出不同的性能。成器表达式看起来比列表解析速度更慢一些,但是它们却把内存需求降到了最小……
上面的结论也不是一定的。随着时间的不同其相对的性能也有所不同(因为Python还在不断的升级优化中,不停的有新的Python版本发布)。所以最好是在自己的电脑上运行计时代码来测一测这些迭代工具在你的Python版本下到底谁快谁慢。
下面我先教大家写计时代码。
Python对代码计时是很容易的。下面我们编写一个模块文件,里面包含了一个通用的计时器工具函数。
File mytimer.py
import time
reps = 1000
repslist = range(reps)
def timer(func,*pargs,**kargs):
start = time.clock()
for i in repslist:
ret = func(*pargs,**kargs)
elapsed = time.clock() - start
return (elapsed,ret)
对于某些同学,上面代码可能有点难懂,不用担心,目前不需要全部都懂。目前只需要明白这个模块主要是通过获取开始时间、然后调用传入的函数固定的次数并且用开始时间减去停止时间,从而对传入的函数进行计时。需要注意以下几点:
•Python的time模块允许访问当前时间,精度随着每个平台而有所不同。在Windows上,这个调用号称能够达到微妙的精度,已经相当准确了。
•range调用放到了计时循环之外,因此,它的构建成本不会计算到Python 2.6的计时函数中。在Python 3.0的range是一个迭代器,因此这个步骤是不需要的(但做了也无伤大雅)。
•reps计数是一个全局变量,如果需要的话,导入者可以修改它:mytimer.reps = N。
当这些完成后,所有调用的总的使用时间在一个元组中返回,还带有被计时的函数的最终返回值,以便调用者可以验证其操作。
计时器模块我们已经写好了,下面就使用它来对比一下各种迭代工具谁最快。
# File timeseqs.py
import sys,mytimer # Import timer function
reps = 10000
repslist = range(reps) # Hoist range out in 2.6
def forLoop():
res = []
for x in repslist:
res.append(abs(x))
return res
def listComp():
return [abs(x) for x in repslist]
def mapCall():
return list(map(abs,repslist)) # Use list in 3.0 only
def genExpr():
return list(abs(x) for x in repslist) # list forces results
def genFunc():
def gen():
for x in repslist:
yield abs(x)
return list(gen())
print(sys.version)
for test in (forLoop,listComp,mapCall,genExpr,genFunc):
elapsed,result = mytimer.timer(test)
print ('-' * 33)
print ('%-9s: %.5f => [%s...%s]' %
(test.__name__,elapsed,result[0],result[-1]))
这段脚本测试了五种迭代工具,每种都执行了一千万次级别的步骤,也就是说,五个测试中的每一个都构建了拥有10000个元素的列表1000次。
注意,我们必须通过内置的list调用来运行生成器表达式和函数结果,从而迫使它们产生其所有的值;如果没有这么做,可能会得到并没有真正工作的生成器。在(仅在)Python 3.0中,我们必须对map结果做同样的事情,因为它现在也是一个可迭代对象。
上面脚本在我自己的笔记本上得到了如下的结果——map比列表解析略微快一点,但二者都比for循环要快很多,生成器表达式和函数速度居中。
C:\misc>c:\python30\python timeseqs.py
3.0.1 (r301:69561,Feb 13 2009,20:04:18) [MSC v.1500 32 bit (Intel)]
---------------------------------
forLoop : 2.64441 => [0...9999]
---------------------------------
listComp : 1.60110 => [0...9999]
---------------------------------
mapCall : 1.41977 => [0...9999]
---------------------------------
genExpr : 2.21758 => [0...9999]
---------------------------------
genFunc : 2.18696 => [0...9999]
不要猜测哪种方法会执行的最快,最好的办法是在自己的计算机上、用自己的Python版本,对自己的代码计时。其实性能应该不是你编写Python代码时首要关心的问题——要优化Python代码,你应该做的第一件事情就是不要优化Python代码!首先要为了可读性和简单性而编写代码,然后,如果需要的话并且只有在需要的时候,再优化。
点赞,收藏,谢谢!