Python 常量操作的编译器优化
下面第0个循环的运行速度*比第1个循环快得多(Python-2.7为3倍,Python-3.4为5倍): 似乎Python在给定Python 常量操作的编译器优化,python,optimization,compilation,Python,Optimization,Compilation,下面第0个循环的运行速度*比第1个循环快得多(Python-2.7为3倍,Python-3.4为5倍): 似乎Python在给定{“a”、“e”、“i”、“o”、“u”}时只构建一次集,而在给定集(“aeiou”)时,每次都会在需要时构建集 这是正确的吗?如果是这样,为什么Python不优化后者 *使用time python-c''进行测量,在第一种情况下,您在编译时创建一次集合(当python代码编译为python字节ops时)。在第二个循环中,为循环的每个迭代创建一次集合。在每个循环中调
{“a”、“e”、“i”、“o”、“u”}
时只构建一次集,而在给定集(“aeiou”)
时,每次都会在需要时构建集
这是正确的吗?如果是这样,为什么Python不优化后者
*使用
time python-c''
进行测量,在第一种情况下,您在编译时创建一次集合(当python代码编译为python字节ops时)。在第二个循环中,为循环的每个迭代创建一次集合。在每个循环中调用构造函数。请重试:
import time
start = time.time()
for x in range(0,999999):
"u" in {"a", "e", "i", "o", "u"}
print time.time() - start, "for dictionary look-up"
start = time.time()
for x in range(0,999999):
"u" in ["a", "e", "i", "o", "u"]
print time.time() - start, "for list look-up" start = time.time()
for x in range(0,999999):
"u" in set("aeiou")
print time.time() - start, "for set construction"
start = time.time()
vowel = set("aeiou")
for x in range(0,999999):
"u" in vowel
print time.time() - start, "for set reference"
这给了时代:
0.292190074921 for dictionary look-up
0.160042047501 for list look-up
0.529402971268 for set construction
0.098151922226 for set reference
我根据您的代码片段创建了函数f1和f2(分别来自#0和#1)。然后我使用dis模块。长话短说,您可以看到,在循环的第二种情况下(在第二个dis中为31),正在调用set构造函数。而常数仅在第一个数据集中加载(在第一个数据集中加载25个)
Python解释器不会将set(“aeiou”)
识别为常量,因为尽管告诉“aeiou”
不会改变很简单,但告诉set
函数是否会改变要困难得多
解释器可以检查set() 相关:为什么Python会将函数调用识别为常量?用户可以将set
变量分配给任何对象,而文字则不是这样。正如我在另一篇文章的回答中所说,这个优化是在Python3.2中添加的:@Ashwini:Ahhh。我现在明白了。我的错。
import time
start = time.time()
for x in range(0,999999):
"u" in {"a", "e", "i", "o", "u"}
print time.time() - start, "for dictionary look-up"
start = time.time()
for x in range(0,999999):
"u" in ["a", "e", "i", "o", "u"]
print time.time() - start, "for list look-up" start = time.time()
for x in range(0,999999):
"u" in set("aeiou")
print time.time() - start, "for set construction"
start = time.time()
vowel = set("aeiou")
for x in range(0,999999):
"u" in vowel
print time.time() - start, "for set reference"
0.292190074921 for dictionary look-up
0.160042047501 for list look-up
0.529402971268 for set construction
0.098151922226 for set reference
In [20]: dis.dis(f1)
2 0 SETUP_LOOP 33 (to 36)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (0)
9 LOAD_CONST 2 (999999)
12 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
15 GET_ITER
>> 16 FOR_ITER 16 (to 35)
19 STORE_FAST 0 (x)
3 22 LOAD_CONST 3 ('u')
25 LOAD_CONST 8 (frozenset({'e', 'o', 'a', 'u', 'i'}))
28 COMPARE_OP 6 (in)
31 POP_TOP
32 JUMP_ABSOLUTE 16
>> 35 POP_BLOCK
>> 36 LOAD_CONST 0 (None)
39 RETURN_VALUE
In [21]: dis.dis(f2)
2 0 SETUP_LOOP 39 (to 42)
3 LOAD_GLOBAL 0 (range)
6 LOAD_CONST 1 (0)
9 LOAD_CONST 2 (999999)
12 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
15 GET_ITER
>> 16 FOR_ITER 22 (to 41)
19 STORE_FAST 0 (x)
3 22 LOAD_CONST 3 ('u')
25 LOAD_GLOBAL 1 (set)
28 LOAD_CONST 4 ('aeiou')
31 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
34 COMPARE_OP 6 (in)
37 POP_TOP
38 JUMP_ABSOLUTE 16
>> 41 POP_BLOCK
>> 42 LOAD_CONST 0 (None)
45 RETURN_VALUE