Python 为什么a+;=x比a=a+慢;x?

Python 为什么a+;=x比a=a+慢;x?,python,python-3.3,Python,Python 3.3,我正在对一个python程序进行优化,但速度有问题。 我在另一个文档上玩,其中有各种各样的东西出现在我的程序中,这些东西可能会影响执行的总速度 我发现: 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秒来执行,而第二个脚本通常需要1,36-1.37秒(使用cProfile) 知道为什

我正在对一个python程序进行优化,但速度有问题。 我在另一个文档上玩,其中有各种各样的东西出现在我的程序中,这些东西可能会影响执行的总速度

我发现:

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秒来执行,而第二个脚本通常需要1,36-1.37秒(使用cProfile)

知道为什么会这样吗?谢谢:)

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

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

使用
timeit
显示这两个版本太接近,无法调用(默认为100万次迭代):

两个操作都是一个字节码:

>>> 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        
使用该选项进行适当的计时。它避免了常见的陷阱,为您的平台使用最精确的计时器实现,并通过多次重复测试代码来尽量减少操作系统调度的影响

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

使用
timeit
显示这两个版本太接近,无法调用(默认为100万次迭代):

两个操作都是一个字节码:

>>> 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        

a+=x
基本上不是增量操作。您正在将变量
a+x
再次分配给
a
。这与使用
a=a+x
为变量赋值几乎相同

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

+++++编辑到DSM

Python中的整数是不可变的:如果定义了

a=5

b=5


所以要“增加”b,你必须“重新分配”它到
b
,这就是我的意思

a+=x
基本上不是增量操作。您正在将变量
a+x
再次分配给
a
。这与使用
a=a+x
为变量赋值几乎相同

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

+++++编辑到DSM

Python中的整数是不可变的:如果定义了

a=5

b=5


所以要“增加”b,你必须“重新分配”它到
b
,这就是我的意思

dis.dis()
说什么??我觉得
a+=x
应该稍微快一点,就地版本稍微慢一点,因为
int
没有定义自己的就地添加,即
int
的插槽
nb\u inplace\u add
0
。看看
dis.dis()
说了什么??我觉得
a+=x
应该稍微快一点,就地版本稍微慢一点,因为
int
没有定义自己的就地添加,即
int
的插槽
nb\u inplace\u add
0
。你能简单地解释一下为什么
timeit
更好吗?这很清楚,谢谢。可能是我的计时出错了,下次我会使用“timeit”。请你简单解释一下,为什么
timeit
更好?这很清楚,谢谢。可能我的计时刚刚出错,下次我将使用“timeit”。我不确定你所说的
a+=x
不是增量操作的意思。这与
a=a+x
不同,它们使用不同的特殊方法,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。原则上,它们可以做完全不同的事情。啊,现在你已经澄清了,你指的是整数情况,而不是一般的
a+=x
操作。我不确定你说的
a+=x
不是增量操作的意思。这与
a=a+x
不同,它们使用不同的特殊方法,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。原则上,它们可以做完全不同的事情。啊,现在你已经澄清了,你指的是整数的情况,而不是一般的
a+=x
操作。