Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python interpreted code optimisation

Tags:

Consider the following code snippet:

dict [name] = 0
dict [name] += 1
dict [name] += 1

Does the python interpreter automatically recognise the repeated references to the dictionary value and use a cached local reference instead?, somewhat akin to the aliasing optimisations of C/C++, becoming something like so:

value = dict [name]
value = 0
value += 1
value += 1

Obviously, it's not a big deal to do this manually but I'm curious if it's actually necessary. any insight, feedback, etc is appreciated.

like image 655
Gearoid Murphy Avatar asked Aug 12 '11 18:08

Gearoid Murphy


People also ask

Does Python optimize for loops?

We can optimize loops by vectorizing operations. This is one/two orders of magnitude faster than their pure Python equivalents (especially in numerical computations). Vectorization is something we can get with NumPy. Numpy is a library with efficient data structures designed to hold matrix data.

How do I make code more optimized?

Optimize Program Algorithm For any code, you should always allocate some time to think the right algorithm to use. So, the first task is to select and improve the algorithm which will be frequently used in the code. 2. Avoid Type Conversion Whenever possible, plan to use the same type of variables for processing.


2 Answers

You can run it through the disassembler to find out:

import dis

def test():
    name = 'test'
    tdict = {}
    tdict[name] = 0
    tdict[name] += 1
    tdict[name] += 1

dis.dis(test)

Running this we get:

 13           0 LOAD_CONST               1 ('test')
              3 STORE_FAST               0 (name)

 14           6 BUILD_MAP                0
              9 STORE_FAST               1 (tdict)

 15          12 LOAD_CONST               2 (0)
             15 LOAD_FAST                1 (tdict)
             18 LOAD_FAST                0 (name)
             21 STORE_SUBSCR        

 16          22 LOAD_FAST                1 (tdict)
             25 LOAD_FAST                0 (name)
             28 DUP_TOPX                 2
             31 BINARY_SUBSCR       
             32 LOAD_CONST               3 (1)
             35 INPLACE_ADD         
             36 ROT_THREE           
             37 STORE_SUBSCR        

 17          38 LOAD_FAST                1 (tdict)
             41 LOAD_FAST                0 (name)
             44 DUP_TOPX                 2
             47 BINARY_SUBSCR       
             48 LOAD_CONST               3 (1)
             51 INPLACE_ADD         
             52 ROT_THREE           
             53 STORE_SUBSCR        
             54 LOAD_CONST               0 (None)
             57 RETURN_VALUE        

It looks like, in this case, that LOAD_FAST is loading up the values of tdict and name each time we try to access it to perform the increment, so the answer would appear to be no.

like image 110
Brent Newey Avatar answered Oct 26 '22 06:10

Brent Newey


That type of optimization isn't possible simply by inspecting the code. Your name dict could refer not to a native dictionary, but a user-defined object that implements __setitem__, and that method has to be called three times. At runtime, a sophisticated implementation could note the actual value of the name, and make an optimization, but it can't be done before runtime without breaking some Python semantics.

like image 45
Ned Batchelder Avatar answered Oct 26 '22 06:10

Ned Batchelder