Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python2.7.6 Initialize a big dictionary but Memory would be used up

Excuse my English,

python version:2.7.6 desktop: 4 cpu-core 8G memory script1:

a = {}
a['test1'] = 12345
a['test2'] = 12456
........
and so on
........
a['test4075096'] = 45637

script2:

for i in range(0,4075096):
    a['test' + str(i)] = i

result

When I run the script2, it complete very quickly When I run the script1, it needs large mem and cpu,and my desktop stuck

So does anyone know the reasons behind this phenomenon

like image 389
loyin Avatar asked May 26 '26 10:05

loyin


1 Answers

It's because of that in first code, python has to read your code line by line and load CONST values to memory, while in second part you already have specified the values which would be assigned,and python will created them in memory. So all that python needs to do is iterating over the range object and assign the values to keys.

You can see this behaviour by calling dis.dis() on your functions which demonstrates the relative bytecodes for you:

>>> def foo1():
...   a = {}
...   a['test1'] = 12345
...   a['test2'] = 12456
... 

>>> import dis
>>> 
>>> 
>>> dis.dis(foo1)
  2           0 BUILD_MAP                0
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               1 (12345)
              9 LOAD_FAST                0 (a)
             12 LOAD_CONST               2 ('test1')
             15 STORE_SUBSCR        

  4          16 LOAD_CONST               3 (12456)
             19 LOAD_FAST                0 (a)
             22 LOAD_CONST               4 ('test2')
             25 STORE_SUBSCR        
             26 LOAD_CONST               0 (None)
             29 RETURN_VALUE        
>>> 

>>> def foo2():
...   a = {}
...   for i in range(1,10):
...        a['test + str(i)'] = i
... 
>>> dis.dis(foo2)
  2           0 BUILD_MAP                0
              3 STORE_FAST               0 (a)

  3           6 SETUP_LOOP              33 (to 42)
              9 LOAD_GLOBAL              0 (range)
             12 LOAD_CONST               1 (1)
             15 LOAD_CONST               2 (10)
             18 CALL_FUNCTION            2
             21 GET_ITER            
        >>   22 FOR_ITER                16 (to 41)
             25 STORE_FAST               1 (i)

  4          28 LOAD_FAST                1 (i)
             31 LOAD_FAST                0 (a)
             34 LOAD_CONST               3 ('test + str(i)')
             37 STORE_SUBSCR        
             38 JUMP_ABSOLUTE           22
        >>   41 POP_BLOCK           
        >>   42 LOAD_CONST               0 (None)
             45 RETURN_VALUE        
>>> 
>>> 

If you increase the assignment you can see that the relative bytecode will increases as well :

>>> def foo1():
...    a = {}
...    a['test1'] = 12345
...    a['test2'] = 12456
...    a['test3'] = 12457
... 
>>> dis.dis(foo1)
  2           0 BUILD_MAP                0
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               1 (12345)
              9 LOAD_FAST                0 (a)
             12 LOAD_CONST               2 ('test1')
             15 STORE_SUBSCR        

  4          16 LOAD_CONST               3 (12456)
             19 LOAD_FAST                0 (a)
             22 LOAD_CONST               4 ('test2')
             25 STORE_SUBSCR        

  5          26 LOAD_CONST               5 (12457)
             29 LOAD_FAST                0 (a)
             32 LOAD_CONST               6 ('test3')
             35 STORE_SUBSCR        
             36 LOAD_CONST               0 (None)
             39 RETURN_VALUE   
like image 147
Mazdak Avatar answered May 30 '26 08:05

Mazdak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!