python2.7.6 初始化一个大字典但是内存会被用完
python2.7.6 Initialize a big dictionary but Memory would be used up
请原谅我的英语,
pythonversion:2.7.6
台式机:4cpu-核心8G内存
脚本 1:
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
结果
当我运行脚本2时,它完成得非常快
当我 运行 脚本 1 时,它需要大内存和 cpu,我的桌面卡住了
那么有谁知道这种现象背后的原因
因为在第一段代码中,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
请原谅我的英语,
pythonversion:2.7.6 台式机:4cpu-核心8G内存 脚本 1:
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
结果
当我运行脚本2时,它完成得非常快 当我 运行 脚本 1 时,它需要大内存和 cpu,我的桌面卡住了
那么有谁知道这种现象背后的原因
因为在第一段代码中,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