为什么Python的枚举速度如此之慢?

时间:2009-08-29 21:57:28

标签: python

为什么“枚举”比“xrange + lst [i]”慢?


>>> from timeit import Timer
>>> lst = [1,2,3,0,1,2]*1000
>>> setup = 'from __main__ import lst'
>>> s1 = """
for i in range(len(lst)):
    elem = lst[i]
"""
>>> s2 = """
for i in xrange(len(lst)):
    elem = lst[i]
"""
>>> s3 = """
for i, v in enumerate(lst):
    elem = v
"""
>>> t1 = Timer(s1, setup); t2 = Timer(s2, setup); t3 = Timer(s3, setup)
>>> t1.timeit(3000), t2.timeit(3000), t3.timeit(3000)
(1.9263118636586494, 1.6119261665937992, 1.9606022553145719)
>>> t1.timeit(3000), t2.timeit(3000), t3.timeit(3000)
(1.93520258859715, 1.6145745478824836, 1.9529405971988041)

编辑: 我记得为什么

for i, v in enumerate(lst):
    elem = i, v
慢于
for i in xrange(len(lst)):
    elem = i, lst[i]

2 个答案:

答案 0 :(得分:15)

如果你测量得当,你会发现基本上没有区别(在这个例子中,枚举在微观上比xrange快,但在噪音范围内):

$ python -mtimeit -s'lst=[1,2,3,0,1,2]*1000' 'for i in xrange(len(lst)): elem=lst[i]'
1000 loops, best of 3: 480 usec per loop
$ python -mtimeit -s'lst=[1,2,3,0,1,2]*1000' 'for i, elem in enumerate(lst): pass'
1000 loops, best of 3: 473 usec per loop

(顺便说一句,我总是建议在shell提示符下使用timeit,不要在代码内或在解释器提示符下使用,只是因为输出格式和可用性非常好,单位为衡量时间和一切)。

在您的代码中,您在枚举案例中有一个额外的分配:您在for标题子句中将列表项分配给v,然后再次将v分配给elem;而在xrange情况下,您只需将项目分配一次,即elem。在我的情况下,我当然也只分配一次,当然;你为什么要分配多次?!无论你在循环体中使用elemi做什么,你都可以在我测量的两种形式中完全相同,只是没有你的枚举案例所具有的冗余。

答案 1 :(得分:5)

可能是因为你已经步履蹒跚enumerate。试试这个:

>>> s3 = """
for i, elem in enumerate(lst):
    pass
"""

更新在亚力克特未提及的shell提示符下使用timeit的两个额外原因:

(1)为你做“最好的N” (2)为你获得有意义的结果需要多少次迭代。