Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance difference between __add__ and + operator

I'm reading Learning Python 5th edition and I need some more explanation on this paragraph:

The __add__ method of strings, for example, is what really performs concatenation; Python maps the first of the following to the second internally, though you shouldn't usually use the second form yourself( it's less intuitive, and might even run slower):

>>> S+'NI!'
'spamNI!'
>>> S.__add__('NI!')
'spamNI!'

so my question is, why would it run slower?

like image 435
arianhf Avatar asked Nov 29 '25 18:11

arianhf


1 Answers

>>> def test(a, b):
...     return a + b
... 
>>> def test2(a, b):
...     return a.__add__(b)
... 
>>> import dis
>>> dis.dis(test)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_FAST                1 (b)
              6 BINARY_ADD          
              7 RETURN_VALUE        
>>> dis.dis(test2)
  2           0 LOAD_FAST                0 (a)
              3 LOAD_ATTR                0 (__add__)
              6 LOAD_FAST                1 (b)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE        

1 BINARY_ADD instruction instead of 2 instructions: LOAD_ATTR and CALL_FUNCTION. And since BINARY_ADD does (almost) the same thing (but in C) then we can expect it to be (slightly) faster. The difference will be hardly noticable though.

Side note: so this is similar to how assembly works. Often when there is a single instruction that does the same thing as a sequence of instructions it will perform better. For example in x64 LEA instruction can be replaced with a sequence of other instructions. But they won't perform as well.

But there's a catch (which explains why I've started talking about x64 assembly). Sometimes a single instruction actually performs worse. See the infamous LOOP instruction. There may be many reasons for such a counterintuitive behaviour, like: a bit different assumption, not optimized implementation, historical reasons, a bug and so on, and so on.

Conclusion: in Python + theoretically should be faster than __add__ but always measure.

like image 146
freakish Avatar answered Dec 01 '25 07:12

freakish