2013-07-20 156 views
1

我正在优化一个我遇到速度问题的python程序。 我在另一份文件上播放出现在我的程序中的各种可能影响执行速度的文件。为什么a + = x比a = a + x慢?

我发现:

a = 0 
for x in range(10000000): 
    a += x 
return a 

比稍慢:

a = 0 
for x in range(10000000): 
    a = a + x 
return a 

第一脚本需要几秒钟1.5和1.55之间执行,而第二个需要regulary约1,36-1.37秒(使用cProfile)。

任何想法,为什么这可能是?谢谢:)

+0

'dis.dis()'说什么?我觉得'a + = x'应该稍微快一点 –

+0

就地版本稍微慢一点,因为'int'没有定义自己的原地添加,即'int'的槽'nb_inplace_add'为'0'。请参阅http://hg.python.org/releasing/3.3.1/file/8e5812b35480/Objects/longobject.c#l4918 – nymk

回答

11

使用timeit module做适当的时间。它避免了常见的缺陷,为您的平台使用最精确的计时器实现,并通过重复测试代码许多次,尽量减少操作系统调度的影响。

另一方面,使用探查器会增加大量开销以支持完整的调用堆栈; timeit测量完整的执行时间,而不是堆栈中的单个调用。

使用timeit显示了这两个版本都分不出(默认为1百万次迭代):

>>> timeit.timeit('a += x', 'a = x = 1') 
0.047940969467163086 
>>> timeit.timeit('a = a + x', 'a = x = 1') 
0.04770612716674805 

这两种操作都一个字节码:

>>> def f(): a += x 
... 
>>> def g(): a = a + x 
... 
>>> import dis 
>>> dis.dis(f) 
    1   0 LOAD_FAST    0 (a) 
       3 LOAD_GLOBAL    0 (x) 
       6 INPLACE_ADD   
       7 STORE_FAST    0 (a) 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE   
>>> dis.dis(g) 
    1   0 LOAD_FAST    0 (a) 
       3 LOAD_GLOBAL    0 (x) 
       6 BINARY_ADD   
       7 STORE_FAST    0 (a) 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE   
+0

您能否简单解释一下为什么'timeit'更好? – contradictioned

+0

这是澄清,谢谢。可能我的时机出错了,下次我会用'timeit'。 – Pabce

0

a += x基本上不是一个增量操作。您将再次将变量a + x分配给a。这与分配a = a + x变量的值几乎相同。

正如皮特斯所说,没有理由在时间上有这样的差距。

+++++编辑到DSM

整数在Python是不可改变的:你增加a,如果你增加b如果定义

a = 5

b = 5

以便'增加'b,你必须'重新分配'它b,这就是我的意思。

+0

我不确定你说'a + = x'不是增量操作。它与'a = a + x'不一样,它们使用不同的特殊方法,'__add__'和'__iadd__'。原则上他们可以做完全不同的事情。 – DSM

+0

啊,现在你已经明确指出你特指整数情况,而不是一般的“a + = x”操作。 – DSM

相关问题