您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python内置求和函数与循环性能对比

Python内置求和函数与循环性能对比

速度差实际上大于3倍,但是您首先通过创建一个巨大的内存列表(一百万个整数)来降低这两个版本的速度。将其与时间试用分开:

>>> import timeit
>>> def sum1(lst):
...     s = 0
...     for i in lst:
...         s += i
...     return s
... 
>>> def sum2(lst):
...     return sum(lst)
... 
>>> values = range(1000000)
>>> timeit.timeit('f(lst)', 'from __main__ import sum1 as f, values as lst', number=100)
3.457869052886963
>>> timeit.timeit('f(lst)', 'from __main__ import sum2 as f, values as lst', number=100)
0.6696369647979736

现在,速度差已超过5倍。

for环所解释的Python字节码执行。sum()完全以C代码循环。解释的字节码和C代码间的速度差异很大。

另外,如果C代码可以将总和保留在C类型中,则确保不创建新的Python对象;这适用于intfloat结果。

反汇编的Python版本执行以下操作:

>>> import dis
>>> def sum1():
...     s = 0
...     for i in range(1000000):
...         s += i
...     return s
... 
>>> dis.dis(sum1)
  2           0 LOAD_CONST               1 (0)
              3 STORE_FAST               0 (s)

  3           6 SETUP_LOOP              30 (to 39)
              9 LOAD_GLOBAL              0 (range)
             12 LOAD_CONST               2 (1000000)
             15 CALL_FUNCTION            1
             18 GET_ITER            
        >>   19 FOR_ITER                16 (to 38)
             22 STORE_FAST               1 (i)

  4          25 LOAD_FAST                0 (s)
             28 LOAD_FAST                1 (i)
             31 INPLACE_ADD         
             32 STORE_FAST               0 (s)
             35 JUMP_ABSOLUTE           19
        >>   38 POP_BLOCK

  5     >>   39 LOAD_FAST                0 (s)
             42 RETURN_VALUE

除了解释器循环慢于C之外,INPLACE_ADD还会创建一个新的整数对象(过去255,cpython将小int对象缓存为单例)。

您可以在Python mercurial代码存储库中看到C实现,但是它在注释中明确指出:

/* Fast addition by keeping temporary sums in C instead of new Python objects.
   Assumes all inputs are the same type.  If the assumption fails, default
   to the more general routine.
*/
python 2022/1/1 18:34:09 有224人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶