考虑下面的代码片段:
dict [name] = 0
dict [name] += 1
dict [name] += 1
python解释器是否会自动识别对字典值的重复引用,并使用缓存的本地引用,这有点类似于C/C++的别名优化,如下所示:
value = dict [name]
value = 0
value += 1
value += 1
显然,手动做这件事没什么大不了的,但我很好奇这是否真的有必要。任何洞察力,反馈等,我们都很感激。
发布于 2011-08-13 02:23:01
您可以通过反汇编程序运行它来找出:
import dis
def test():
name = 'test'
tdict = {}
tdict[name] = 0
tdict[name] += 1
tdict[name] += 1
dis.dis(test)
运行下面的代码,我们会得到:
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
看起来,在这种情况下,每次我们尝试访问LOAD_FAST
来执行增量操作时,它都会加载tdict
和name
的值,因此答案似乎是否定的。
发布于 2011-08-13 02:30:25
这种类型的优化不可能仅仅通过检查代码来实现。您的名字dict
可以引用实现__setitem__
的用户定义对象,而不是本机字典,并且该方法必须被调用三次。在运行时,复杂的实现可以注意到名称的实际值,并进行优化,但在运行之前无法在不破坏某些Python语义的情况下完成此操作。
发布于 2011-08-13 02:33:28
不,因为这是行不通的,你甚至用你自己的代码演示了这一点--这实际上并不等同:
>>> a = {}
>>> name = 'x'
>>> a[name] = 0
>>> a[name] += 1
>>> a[name] += 1
>>> a[name] # ok no suprises so far
2
>>> a = {}
>>> a[name] = 0
>>> x = a[name] # x is now literally `0`, not some sort of reference to a[name]
>>> x
0
>>> x += 1
>>> x += 1
>>> a[name] # so this never changed
0
>>>
Python没有C语言的“引用”。您所想的只适用于可变类型,如list
。这是Python的一个非常基本的属性,在编写Python时,您可能会忘记C语言教给您的有关变量的所有内容。
https://stackoverflow.com/questions/7044515
复制相似问题