2012-08-12 48 views

回答

12

有几乎是在工作蟒蛇执行的任何陈述有所不同:

>>> import dis 
>>> def inplace_add(): 
...  a = 0 
...  a += 1 
... 
>>> def add_and_assign(): 
...  a = 0 
...  a = a + 1 
... 
>>> dis.dis(inplace_add) 
    2   0 LOAD_CONST    1 (0) 
       3 STORE_FAST    0 (a) 

    3   6 LOAD_FAST    0 (a) 
       9 LOAD_CONST    2 (1) 
      12 INPLACE_ADD   
      13 STORE_FAST    0 (a) 
      16 LOAD_CONST    0 (None) 
      19 RETURN_VALUE   
>>> dis.dis(add_and_assign) 
    2   0 LOAD_CONST    1 (0) 
       3 STORE_FAST    0 (a) 

    3   6 LOAD_FAST    0 (a) 
       9 LOAD_CONST    2 (1) 
      12 BINARY_ADD   
      13 STORE_FAST    0 (a) 
      16 LOAD_CONST    0 (None) 
      19 RETURN_VALUE   

的区别是一个INPLACE_ADD与一个BINARY_ADD

产生的时序是分不出哪一个会更快:

>>> import timeit 
>>> timeit.timeit('inplace_add', 'from __main__ import inplace_add', number=10000000) 
0.32667088508605957 
>>> timeit.timeit('add_and_assign', 'from __main__ import add_and_assign', number=10000000) 
0.34172606468200684 

因此,在蟒蛇,不同的是可以忽略不计。不要担心。

+0

很好的回答(我不知道'dis'模块,所以谢谢你)。一个考虑因素是执行速度可能会受到给定时间运行的其他进程的影响。因此,我的方法是在一个函数中运行100万次,并在'cProfile'中多次比较执行速度(见下文)。我同意这种差异是微不足道的。 – 2012-08-13 06:22:48

4

都能跟得上

>>> bar = timeit.Timer("a += 1", "a = 0") 
>>> bar.timeit(number=1000000) 
0.064391136169433594 
>>> bar = timeit.Timer("a = a + 1", "a = 0") 
>>> bar.timeit(number=1000000) 
0.064393997192382812 
>>> 
2

是的,但差别很小。

>>> timeit.Timer('x += 1', 'x = 0').timeit(10**8) 
5.7387330532073975 
>>> timeit.Timer('x = x + 1', 'x = 0').timeit(10**8) 
6.04801607131958 
>>> timeit.Timer('x += 1', 'x = 0').timeit(10**8) 
5.790481090545654 
>>> timeit.Timer('x = x + 1', 'x = 0').timeit(10**8) 
6.083467960357666 
1

我把使用cProfile模块稍微不同的方法:

$ python -m cProfile test.py 
    4 function calls in 0.397 seconds 

Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 0.397 0.397 test.py:2(<module>) 
     1 0.205 0.205 0.205 0.205 test.py:2(add1) 
     1 0.192 0.192 0.192 0.192 test.py:6(add2) 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 




[email protected]:~/pyad$ cat test.py 
def add1(a): 
    for x in xrange(10 ** 6): 
     a += 1 

def add2(a): 
    for x in xrange(10 ** 6): 
     a = a + 1 

add1(0) 
add2(0) 

后约20运行我会总结(使用a = a + 1),其ADD2非常稍快,但不是在所有情况下(也许尝试更多的循环)。这可能不是最好的启发式算法,但我认为更大数量的重复次数应该表示性能差异。

编辑 - 结果10个** 9来电:

1 216.119 216.119 216.119 216.119 test.py:2(add1) 
    1 195.364 195.364 195.364 195.364 test.py:6(add2) 
相关问题