python2.7.6初始化一个大字典,但是内存会被耗尽

2024-06-16 14:33:05 发布

您现在位置:Python中文网/ 问答频道 /正文

请原谅我的英语

Python版本:2.7.6 桌面:4核8G内存 脚本1:

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

脚本2:

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

结果

当我运行script2时,它很快就完成了 当我运行script1时,它需要很大的内存和cpu,我的桌面卡住了

那么,有人知道这种现象背后的原因吗


Tags: and内存intest版本脚本forso
1条回答
网友
1楼 · 发布于 2024-06-16 14:33:05

因为在第一段代码中,python必须逐行读取代码并将CONST值加载到内存中,而在第二部分中,您已经指定了要分配的值,python将在内存中创建它们。因此,python需要做的就是迭代range对象并将值赋给键。你知道吗

通过调用函数上的dis.dis()可以看到这种行为,函数为您演示了相关字节码:

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

如果增加赋值,可以看到相对字节码也会增加:

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

相关问题 更多 >