请考虑以下代码段:
dict [name] = 0
dict [name] += 1
dict [name] += 1
python解释器是否自动识别对字典值的重复引用并使用缓存的本地引用?,有点类似于C / C ++的别名优化,变成这样:
value = dict [name]
value = 0
value += 1
value += 1
显然,手动执行此操作并不是一件大事,但我很好奇是否真的有必要。任何见解,反馈等都表示赞赏。
答案 0 :(得分:27)
您可以通过反汇编程序运行它来查找:
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
的值都会加载,所以答案是似乎没有。
答案 1 :(得分:8)
仅通过检查代码就无法实现这种类型的优化。您的名字dict
可能不是指本地字典,而是指实现__setitem__
的用户定义对象,并且该方法必须被调用三次。在运行时,一个复杂的实现可以记录名称的实际值,并进行优化,但是在运行时不能在不破坏某些Python语义的情况下完成。
答案 2 :(得分:1)
不,因为那不起作用,你甚至用自己的代码证明了这一点 - 它实际上并不等同:
>>> 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-ish“引用”。您的想法仅适用于list
等可变类型。这是Python的一个非常基本的属性,你可能应该忘记在编写Python时C教你的变量。
答案 3 :(得分:1)
将您的两个示例更改为以下内容:
#v1.py
di = {}
name = "hallo"
di[name] = 0
for i in range(2000000):
di[name] += 1
和
#v2.py
di = {}
name = "hallo"
di[name] = 0
value = di[name]
for i in range(2000000):
value += 1
您可以在以下测试中看到,v2更快,但pypy更快: - )
$ time python2.7 v1.py
real 0m0.788s
user 0m0.700s
sys 0m0.080s
$ time python2.7 v2.py
real 0m0.586s
user 0m0.490s
sys 0m0.090s
$ time pypy v1.py
real 0m0.203s
user 0m0.210s
sys 0m0.000s
$ time pypy v2.py
real 0m0.117s
user 0m0.080s
sys 0m0.030s
所以:为单个解释器优化代码并不好(我还没有测试过Jython ......),但是当someone优化解释器时它很棒......