首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python: while与while (条件)效率

python: while与while (条件)效率
EN

Stack Overflow用户
提问于 2019-11-03 20:12:09
回答 1查看 844关注 0票数 1

我最近开始学习编程(用Python)。我有两段使用while循环的代码:

代码语言:javascript
复制
a=100000000
#piece of code 1    
while a > 0:
    a-=10
print("done")

#piece of code 2
while True:
    a-=10
    if a <= 0:
       print("done")
       break

两者在功能上是等价的,即它们执行的任务本质上是相同的。出于好奇,我使用time模块使用这两个版本的while循环记录了执行此操作所需的时间。研究结果如下:

代码1: 0.99 s

代码2: 0.89 s

它们显示了基本相同的性能,尽管代码2的部分效率略高一些。这是可以的,因为即使对于非常大的数字,这种差异基本上也是无关紧要的。但是,这对我来说有点出乎意料,因为我认为第一个while循环执行的操作较少。有人能解释一下为什么第二段代码更高效吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-03 21:00:22

我把这些片段放在两个函数中:

代码语言:javascript
复制
def first():
    a=100000000
    while a > 0:
        a-=10

def second():
    a=100000000
    while True:
        a-=10
        if a <= 0:
            break

然后使用了timeit.timeit,实际上是second一直被计时为花费更长的时间(尽管差异非常小)。

代码语言:javascript
复制
from timeit import timeit

timeit(first, number=100)
timeit(second, number=100)

然后,通过从dis文档复制示例来检查字节码。这表明字节码对于这两个代码段几乎是相同的,唯一的区别是操作码的排序方式,并且second包含一个额外的指令,即BREAK_LOOP

代码语言:javascript
复制
import dis
from collections import Counter

first_bytecode = dis.Bytecode(first)
for instr in first_bytecode:
    print(instr.opname)

second_bytecode = dis.Bytecode(second)
for instr in second_bytecode:
    print(instr.opname)

# easier to compare with Counters
first_b = Counter(x.opname for x in first_bytecode)
sec_b = Counter(x.opname for x in second_bytecode)

最后,人们可能会认为顺序可能会产生不同(而且可能),但为了进行公平的比较,second应该首先检查中断条件,然后再从a中减去。然后考虑第三项职能:

代码语言:javascript
复制
def third():
    a=100000000
    while True:
        if a <= 0:
            break
        a-=10

third的字节码进行比较,您会发现它的排序实际上与first的字节码相同,唯一的区别是阻塞在中间某个位置的单个BREAK_LOOP

如果有什么希望的话,我希望这向您展示一个操作码的执行对于代码的总体性能来说是多么的微不足道。我认为唐纳德·克努斯的不朽的话语特别适合这一场合:

我们应该忘记小效率,说大约97%的时候:过早的优化是所有邪恶的根源。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58684208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档