当前位置: 首页 > 知识库问答 >
问题:

为什么set()使这段代码运行得更快?

薛高澹
2023-03-14

我写了一些欧拉问题35的代码:

#Project Euler: Problem 35

import time

start = time.time()

def sieve_erat(n):
    '''creates list of all primes < n'''
    x = range(2,n)
    b = 0
    while x[b] < int(n ** 0.5) + 1:
        x = filter(lambda y: y % x[b] != 0 or y == x[b], x)
        b += 1
    else:
        return x

def circularPrimes(n):
    '''returns # of circular primes below n'''
    count = 0
    primes = sieve_erat(n)
    b = set(primes)
    for prime in primes:
        inc = 0
        a = str(prime)
        while inc < len(a):
            if int(a) not in b:
                break
            a = a[-1] + a[0:len(a) - 1]
            inc += 1
        else:
            count += 1
    else:
        return count

print circularPrimes(1000000)
elapsed = (time.time() - start)
print "Found in %s seconds" % elapsed

我想知道为什么这个代码(上图)运行得这么快,当我设置b=set(primes)循环素数函数中。这段代码的运行时间约为8秒。最初,我没有设置b=set(primes),我的循环Primes函数是这样的:

def circularPrimes(n):
    '''returns # of circular primes below n'''
    count = 0
    primes = sieve_erat(n)
    for prime in primes:
        inc = 0
        a = str(prime)
        while inc < len(a):
            if int(a) not in primes:
                break
            a = a[-1] + a[0:len(a) - 1]
            inc += 1
        else:
            count += 1
    else:
        return count

我的初始代码(没有b=set(primes))运行了很长时间,我没有等它完成。我很好奇,为什么这两段代码在运行时间上存在如此大的差异,因为我不相信primes会有任何重复项,这会使迭代花费如此长的时间,以至于迭代set(primes)。也许我对set()的想法是错误的。欢迎任何帮助。

共有1个答案

邴修远
2023-03-14

我相信这里的罪魁祸首是如果int(a)不在b:中。集在内部实现为哈希表,这意味着检查成员资格比检查列表要便宜得多(因为您只需要检查冲突)。

你可以在这里查看布景的内部。

 类似资料:
  • 问题内容: Java很慢。 这似乎不仅仅是一个“城市传奇”。由于延迟,您不将其用于实时编码,也不将其用于集群/并行计算。有成千上万的基准测试,特别是“ Java vs C#vs C ++”。 http://benchmarksgame.alioth.debian.org/ 根据以上站点,不仅Java性能几乎与C一样好(远远没有C),而且Scala和Clojure(两种在JVM上运行的功能语言)都具

  • 我想了解为什么一段代码不会抛出NullPointerException。 请考虑以下代码: 方法被重复调用,同时以下代码在单独的线程中运行: 只有一个实例。 从不引发NullPointerException。 但是,当方法暂停时,即使暂停0毫秒,也会按预期引发NullPointerException: 我的理解是,在理论上,在检查和调用之间存在竞争条件。在实践中,如果不引入暂停(即从后续方法调用中

  • 在方法或类范围内,下面的行编译(带有警告): 在类作用域中,变量获取其默认值,以下给出未定义引用错误: 这难道不是第一个应该以相同的未定义引用错误结束吗?或者第二行应该编译?或者我错过了什么?

  • 我有一些流处理代码,它接受一个单词流并对它们执行一些操作,然后将它们简化为一个,其中包含单词作为键,单词的出现次数作为值。为了代码的简洁性,我使用了jOOL库的类,其中包含许多有用的快捷方法。 类型中的方法不适用于参数 type未定义此处适用的 为什么的行为与有任何不同,我(也许是天真地)认为它是直接等效的,为什么编译器在使用它时不能处理它? (是的,我知道我可以通过将以前的应用程序移到操作中来删

  • 这段代码是我用Java Swing制作的Tic-Tac-Toe程序的一部分。为什么在添加用于添加按钮的for语句时返回NullPointerException?