我正在尝试使用此代码
制作小于n的素数列表stderr
但这需要超过5秒,是程序还是只是我的电脑。我刚才给它洒了一杯饮料,它不再那么快了,所以它可能就是电脑。如果是程序,我应该怎么做才能加快它。
我的想法是,break语句只是在范围内跳出for k循环,但它应该在范围内打破for i循环。
答案 0 :(得分:1)
两个简单的改进是:
2
除外。 primes_n(10**5)
:
from math import sqrt
def primes_n(n):
primes = [2]
for i in range(3, n+1, 2):
for p in primes:
if p > int(sqrt(i)):
primes.append(i)
break
if i % k == 0:
break
return primes
如果你想比这更快,你将不得不实施sieve of Eratosthenes。
在此处查看一些最快的实施:Fastest way to list all primes below N。
答案 1 :(得分:1)
这很慢,因为有999900个循环运行(减去因break
而跳过的循环,但也不计算从k in primes
完成的循环。)
您可以采取一些优化措施:
k in primes
最终会更快)。如果您需要,请返回sorted(primes)
。但是,通过下一次优化,这一点毫无意义。我的运行时间:
i
平方根下的素数:27ms;仍然比原版快2.9倍,但比之前的注意:我使用的是pypy,所以我的运行时间为77毫秒,而你的5秒是部分原因。但是当我在常规的python 2.7解释器上运行时,我得到了980毫秒(.98秒)。因此,您似乎还拥有一台速度较慢的计算机,以及一种优化不佳的算法。
所以,这是我的最终代码:
def primes_n(n):
primes = [2]
for i in range(3, n+1):
for prime in primes:
if i % prime == 0:
break
else:
primes.append(i)
return primes
更新:我在中间停止写我的午餐,所以我没有看到另一个人的额外优化。
我在使用平方根位方面做得很差,所以使用它实际上并不慢(实现得很差)。因此,在应用他的优化之后,再加上我在回答评论中提到的小问题,我得到3ms的运行时间,比我之前的最佳速度快6倍。这是代码:
def primes3_2(n):
primes = [2]
for i in range(3, n+1, 2):
root_of_i = sqrt(i)
for prime in primes:
if prime <= root_of_i:
primes.append(i)
break
if i % prime == 0:
break
return primes