Python 使用if语句的While循环比While循环快
我正在测试循环中if语句的速度及其对速度的影响。我发现,if语句始终提高了性能。我的代码:Python 使用if语句的While循环比While循环快,python,performance,if-statement,python-3.x,while-loop,Python,Performance,If Statement,Python 3.x,While Loop,我正在测试循环中if语句的速度及其对速度的影响。我发现,if语句始终提高了性能。我的代码: import time t = time.time start = t() x = 0 while x < 10000000: x += 1 time1 = t() x = 0 while x < 10000000: x += 1 if True: pass time2 = t() print(start) print(time1 - start)
import time
t = time.time
start = t()
x = 0
while x < 10000000:
x += 1
time1 = t()
x = 0
while x < 10000000:
x += 1
if True:
pass
time2 = t()
print(start)
print(time1 - start) # Time for simple while-loop
print(time2 - time1) # Time for while+if
这完全违反直觉。while-if循环的工作速度比标准while循环稍快。几乎每次我运行它时都会发生这种情况;也许每20次中就有1次需要更长的时间。有人知道为什么吗?我猜编译器会删除if-True块,因为它是常量 当我跑步时,我从你那里得到的结果大多是相反的。我可能只是执行环境的随机影响 1355519587.2 0.832797050476 1.04382395744 1355519590.03 0.863899946213 1.09347200394 1355519593.72 0.831655025482 1.05389809608 1355519599.71 0.831452131271 1.41783499718 1355519602.99 0.815280914307 1.05724310875 1355519605.72 0.826404094696 1.05700492859 1355519608.94 0.827296972275
1.07807898521dis显示if语句的while循环有更多步骤
In [4]: dis.dis(t2)
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (x)
3 6 SETUP_LOOP 26 (to 35)
>> 9 LOAD_FAST 0 (x)
12 LOAD_CONST 2 (10000000)
15 COMPARE_OP 0 (<)
18 POP_JUMP_IF_FALSE 34
4 21 LOAD_FAST 0 (x)
24 LOAD_CONST 3 (1)
27 INPLACE_ADD
28 STORE_FAST 0 (x)
31 JUMP_ABSOLUTE 9
>> 34 POP_BLOCK
>> 35 LOAD_CONST 0 (None)
38 RETURN_VALUE
In [5]: dis.dis(t1)
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (x)
3 6 SETUP_LOOP 35 (to 44)
>> 9 LOAD_FAST 0 (x)
12 LOAD_CONST 2 (10000000)
15 COMPARE_OP 0 (<)
18 POP_JUMP_IF_FALSE 43
4 21 LOAD_FAST 0 (x)
24 LOAD_CONST 3 (1)
27 INPLACE_ADD
28 STORE_FAST 0 (x)
5 31 LOAD_GLOBAL 0 (True)
34 POP_JUMP_IF_FALSE 9
6 37 JUMP_ABSOLUTE 9
40 JUMP_ABSOLUTE 9
>> 43 POP_BLOCK
>> 44 LOAD_CONST 0 (None)
47 RETURN_VALUE
[4]中的:dis.dis(t2)
2 0负载常数1(0)
3存储单元快速0(x)
3 6设置回路26(至35)
>>9快速加载0(x)
12负载常数2(10000000)
15比较操作0(>34个弹出块
>>35负载常数0(无)
38返回值
In[5]:dis.dis(t1)
2 0负载常数1(0)
3存储单元快速0(x)
3 6设置回路35(至44)
>>9快速加载0(x)
12负载常数2(10000000)
15比较操作0(>43弹出块
>>44负载常数0(无)
47返回值
如果将x=0
移出两个计时块会发生什么?我打赌您看到的是解释器必须为第一个块分配x
,而不是第二个块。这里不一样,tho';我有类似的计时:$python t.py 1355519439.65 1.92616391182 2.650105595322
;在python 2.7.3上运行的结果是相同的吗如果您先运行if循环,然后运行没有if循环的循环?对我来说,第一个循环总是更快。我得到了您在2.7中所期望的结果,以及在3.2中所得到的奇怪结果。第二个版本(在Python 3.2.3中)的运行时间也一直比预期的要长。请记住,time.time()
不是分析程序的正确方法(因为其他任务可能会影响结果)。使用timeit.timeit()
相反。哪个引擎?没有即时编译器或任何东西。至少在CPython中没有。事实上,根本没有编译器,我们这里讨论的是Python。同意。我的结果是:1355519852.98、0.830796003342、1.11595201492和Python 2.7。1@TimPietzcker,它是2.7.1。Python会编译,但会转换为字节码。您不能执行raw text在大多数操作环境中使用。@delnan:你能给出一个例子或一些文档的链接,说明编译器可以做什么样的优化吗?显然,它不能删除空的if
语句。@TimPietzcker我认为这没有文档记录,因为它是一个实现细节,很少有什么关系我看到的Optimizer在中。当然,还有来源:(有很多评论详细说明了所执行的优化)。请参阅第446行,了解根据常量进行的跳转优化。感谢您发布这篇文章,我以前不知道dis模块。但是,while-if循环运行得更快,即使在非常低的级别,它也需要更多的步骤,这一点仍然令人困惑。
In [4]: dis.dis(t2)
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (x)
3 6 SETUP_LOOP 26 (to 35)
>> 9 LOAD_FAST 0 (x)
12 LOAD_CONST 2 (10000000)
15 COMPARE_OP 0 (<)
18 POP_JUMP_IF_FALSE 34
4 21 LOAD_FAST 0 (x)
24 LOAD_CONST 3 (1)
27 INPLACE_ADD
28 STORE_FAST 0 (x)
31 JUMP_ABSOLUTE 9
>> 34 POP_BLOCK
>> 35 LOAD_CONST 0 (None)
38 RETURN_VALUE
In [5]: dis.dis(t1)
2 0 LOAD_CONST 1 (0)
3 STORE_FAST 0 (x)
3 6 SETUP_LOOP 35 (to 44)
>> 9 LOAD_FAST 0 (x)
12 LOAD_CONST 2 (10000000)
15 COMPARE_OP 0 (<)
18 POP_JUMP_IF_FALSE 43
4 21 LOAD_FAST 0 (x)
24 LOAD_CONST 3 (1)
27 INPLACE_ADD
28 STORE_FAST 0 (x)
5 31 LOAD_GLOBAL 0 (True)
34 POP_JUMP_IF_FALSE 9
6 37 JUMP_ABSOLUTE 9
40 JUMP_ABSOLUTE 9
>> 43 POP_BLOCK
>> 44 LOAD_CONST 0 (None)
47 RETURN_VALUE