【发布时间】:2013-05-19 09:59:56
【问题描述】:
如果您查看以下时序:
C:\Users\Henry>python -m timeit -s "mul = int.__mul__" "reduce(mul,range(10000))"
1000 loops, best of 3: 908 usec per loop
C:\Users\Henry>python -m timeit -s "from operator import mul" "reduce(mul,range(10000))"
1000 loops, best of 3: 410 usec per loop
两者的执行速度存在显着差异
reduce(int.__mul__,range(10000)) 和 reduce(mul,range(10000)) 后者更快。
使用dis 模块查看发生了什么:
使用int.__mul__方法:
C:\Users\Henry>python
Python 2.7.4 (default, Apr 6 2013, 19:55:15) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> mul = int.__mul__
>>> def test():
... mul(1,2)
...
>>> import dis
>>> dis.dis(test)
2 0 LOAD_GLOBAL 0 (mul)
3 LOAD_CONST 1 (1)
6 LOAD_CONST 2 (2)
9 CALL_FUNCTION 2
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
>>>
还有运算符mul方法
C:\Users\Henry>python
Python 2.7.4 (default, Apr 6 2013, 19:55:15) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from operator import mul
>>> def test():
... mul(1,2)
...
>>> import dis
>>> dis.dis(test)
2 0 LOAD_GLOBAL 0 (mul)
3 LOAD_CONST 1 (1)
6 LOAD_CONST 2 (2)
9 CALL_FUNCTION 2
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
>>>
它们看起来一样,那么为什么执行速度会有所不同?我指的是Python的CPython实现
同样的情况发生在 python3 上:
$ python3 -m timeit -s 'mul=int.__mul__;from functools import reduce' 'reduce(mul, range(10000))'
1000 loops, best of 3: 1.18 msec per loop
$ python3 -m timeit -s 'from operator import mul;from functools import reduce' 'reduce(mul, range(10000))'
1000 loops, best of 3: 643 usec per loop
$ python3 -m timeit -s 'mul=lambda x,y:x*y;from functools import reduce' 'reduce(mul, range(10000))'
1000 loops, best of 3: 1.26 msec per loop
【问题讨论】:
-
您正在查看
test()的字节码反汇编,它只调用mul,因此在两种情况下都是相同的。mul的两个实现可能不同。 -
@HristoIliev 谢谢,我没有说它只是拆卸测试。我想这更有意义。到时候我会进一步研究这些是如何实现的。
-
你用的是python二吗?问题可能是 int 的 mul 会溢出并调用 long 的 mul 而操作员避免这种额外的调用。
-
使用
profile.run('reduce(mul, range(10000))')会显示更奇怪的结果:int.__mul__和operator.mul都只执行了 5 个函数调用(这意味着某些东西已被优化)。使用mul=lambda x,y:x*y执行大约10k函数调用(不应优化),但所用时间与int.__mul__相同。 -
@Bakuriu 我根本不相信这与这个问题有关(您可能应该将其编辑掉)函数调用似乎是由 Python 本身而不是由 @987654339 中的函数调用的函数调用@调用
C中的函数@