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时)。在第二个循环中,为循环的每个迭代创建一次集合。在每个循环中调

下面第0个循环的运行速度*比第1个循环快得多(Python-2.7为3倍,Python-3.4为5倍):

似乎Python在给定
{“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