1

Pythonでも同じかどうかはわかりません。

誰もそれを試したことがありますか?

http://docs.python.org/library/operator#operator.iadd

4

4 に答える 4

16

どちらのステートメントに対しても python が実行する作業に違いはほとんどありません。

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

違いは aINPLACE_ADDと aBINARY_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

したがって、Python では、違いはごくわずかです。ご心配なく。

于 2012-08-12T20:04:59.647 に答える
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
>>>
于 2012-08-12T20:04:44.470 に答える
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
于 2012-08-12T20:08:38.563 に答える
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}




aaron@zebrafish:~/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 回実行した後、add2 ( を使用a = a + 1) が非常にわずかに高速であると結論付けましたが、すべての場合ではありませんでした (おそらく、より多くのループで試してみてください)。これはおそらく最良のヒューリスティックではありませんが、より大きな数でより多くの繰り返しを行うと、パフォーマンスの違いが示されるはずです。

編集 - 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)
于 2012-08-13T06:08:08.037 に答える