Reputation: 131
I ran some quick benchmarking using timeit.repeat
comparing two different ways to use an _accumulator_
.
def testAccumPlusEqual():
x = 0
for i in range(100):
x += 1
return x
def testAccumEqualPlus():
x = 0
for i in range(100):
x = x + 1
return x
My implementation of timeit.repeat
is:
if __name__ == '__main__':
import timeit
print(timeit.repeat("testAccumPlusEqual()",
setup="from __main__ import testAccumPlusEqual"))
print(timeit.repeat("testAccumEqualPlus()",
setup="from __main__ import testAccumEqualPlus"))
The results are found below:
>>>
[8.824021608811469, 8.80440620087051, 8.791231916848997]
[8.101681307351758, 8.143080002052649, 8.181129610882778]
Granted, in the grand scheme of things, this time difference may not be noticeable, but if used in large scale it could lead to a slow down. So I guess I'm really asking:
From everywhere I've seen, the de facto standard is to accumulate with +=
, but should that be the case still?
Why would +=
perform worse than x=x+
?
NOTE: Using CPython 3.3.2 on Windows 7 64bit(using 32bit version of python)
Upvotes: 0
Views: 488
Reputation: 117380
It's not actually an answer, but it could help you to understand what happens in you Python code. You can call dis on both of functions and get:
>>> import dis
>>> dis.dis(testAccumEqualPlus)
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (x)
3 6 SETUP_LOOP 30 (to 39)
9 LOAD_GLOBAL 0 (range)
12 LOAD_CONST 2 (100)
15 CALL_FUNCTION 1
18 GET_ITER
>> 19 FOR_ITER 16 (to 38)
22 STORE_FAST 1 (i)
4 25 LOAD_FAST 0 (x)
28 LOAD_CONST 3 (1)
31 BINARY_ADD
32 STORE_FAST 0 (x)
35 JUMP_ABSOLUTE 19
>> 38 POP_BLOCK
5 >> 39 LOAD_FAST 0 (x)
42 RETURN_VALUE
>>> dis.dis(testAccumPlusEqual)
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (x)
3 6 SETUP_LOOP 30 (to 39)
9 LOAD_GLOBAL 0 (range)
12 LOAD_CONST 2 (100)
15 CALL_FUNCTION 1
18 GET_ITER
>> 19 FOR_ITER 16 (to 38)
22 STORE_FAST 1 (i)
4 25 LOAD_FAST 0 (x)
28 LOAD_CONST 3 (1)
31 INPLACE_ADD
32 STORE_FAST 0 (x)
35 JUMP_ABSOLUTE 19
>> 38 POP_BLOCK
5 >> 39 LOAD_FAST 0 (x)
42 RETURN_VALUE
As you see, the only difference is INPLACE_ADD
for +=
and BINARY_ADD
for = .. +
Upvotes: 2