为什么while循环比for循环更有效?

时间:2014-11-23 18:47:17

标签: python performance benchmarking

我正在研究Eratosthenes的Sieve,我正在分析如何从候选人范围中过滤非素数。

为了测试,我使用了这个命令:

import timeit
print timeit.timeit(stmt="sieve(1000)", setup='from sieve import sieve', number=1000)

这就是我目前所拥有的:

def sieve(limit):
    primes = [2]
    pRange = range(3, limit, 2)
    while pRange:
        p = pRange.pop(0)
        filter_range = range(p**2, limit, p << 1)
        pRange = filter(lambda x: x not in filter_range, pRange)
        primes.append(p)
    return primes

Seconds =&gt; 5.42698788643

然后我想如果我要从范围中弹出第一个元素,我可能想这样写:

def sieve(limit):
    primes = [2]
    pRange = range(3, limit, 2)
    for p in pRange:
        filter_range = range(p**2, limit, p << 1)
        pRange = filter(lambda x: x not in filter_range, pRange)
        primes.append(p)
    return primes

但事实证明15.7085180283秒后速度要慢得多。

为什么会这样? for循环是否迭代了pRange的初始值并且没有更新?

1 个答案:

答案 0 :(得分:3)

for p in pRange:

这会评估pRange,将其转换为列表(Python 2)或生成器(Python 3),然后遍历范围中的项目。 不会重新评估pRange

无论哪种方式都会导致比while循环更多的循环迭代,因为后者每次循环都会重新评估范围。

请记住,在Python中,变量是所有引用。即使a = 5之类的意思是“设置a来引用值为5的整数常量。”同样,pRange = filter(...)表示“获取filter(...)返回的对象,并设置pRange以引用它。释放对用于引用的任何值pRange的引用(可能垃圾收集它以后如果没有引用它。)“