列出 N 以下所有素数的最快方法
Posted
技术标签:
【中文标题】列出 N 以下所有素数的最快方法【英文标题】:Fastest way to list all primes below N 【发布时间】:2011-01-05 07:38:25 【问题描述】:这是我能想到的最好的算法。
def get_primes(n):
numbers = set(range(n, 1, -1))
primes = []
while numbers:
p = numbers.pop()
primes.append(p)
numbers.difference_update(set(range(p*2, n+1, p)))
return primes
>>> timeit.Timer(stmt='get_primes.get_primes(1000000)', setup='import get_primes').timeit(1)
1.1499958793645562
可以做得更快吗?
此代码有一个缺陷:由于numbers
是一个无序集合,因此不能保证numbers.pop()
会从集合中删除最小的数字。尽管如此,它对某些输入数字有效(至少对我而言):
>>> sum(get_primes(2000000))
142913828922L
#That's the correct sum of all numbers below 2 million
>>> 529 in get_primes(1000)
False
>>> 529 in get_primes(530)
True
【问题讨论】:
如果数字声明为 numbers = set(range(n, 2, -2)),则相关代码片段会快得多。但无法击败 sundaram3。感谢您的提问。 如果答案中有 Python 3 版本的函数会很好。 肯定有一个库可以做到这一点,所以我们不必自己动手> xkcd 承诺 Python 就像import antigravity
一样简单。没有像require 'prime'; Prime.take(10)
(Ruby)这样的东西吗?
@ColonelPanic 碰巧我为 Py3 更新了 github.com/jaredks/pyprimesieve 并添加到 PyPi。它肯定比这些更快,但不是数量级 - 比最好的 numpy 版本快约 5 倍。
@ColonelPanic:我认为编辑旧答案以注意它们已经老化是合适的,因为这使它成为更有用的资源。如果“已接受”的答案不再是最佳答案,则可以在问题中编辑注释,并使用 2015 年的更新来为人们指出当前的最佳方法。
【参考方案1】:
Pure Python中最快的初筛:
from itertools import compress
def half_sieve(n):
"""
Returns a list of prime numbers less than `n`.
"""
if n <= 2:
return []
sieve = bytearray([True]) * (n // 2)
for i in range(3, int(n ** 0.5) + 1, 2):
if sieve[i // 2]:
sieve[i * i // 2::i] = bytearray((n - i * i - 1) // (2 * i) + 1)
primes = list(compress(range(1, n, 2), sieve))
primes[0] = 2
return primes
我针对速度和内存优化了 埃拉托色尼筛。
基准测试
from time import clock
import platform
def benchmark(iterations, limit):
start = clock()
for x in range(iterations):
half_sieve(limit)
end = clock() - start
print(f'end/iterations:.4f seconds for primes < limit')
if __name__ == '__main__':
print(platform.python_version())
print(platform.platform())
print(platform.processor())
it = 10
for pw in range(4, 9):
benchmark(it, 10**pw)
输出
>>> 3.6.7
>>> Windows-10-10.0.17763-SP0
>>> Intel64 Family 6 Model 78 Stepping 3, GenuineIntel
>>> 0.0003 seconds for primes < 10000
>>> 0.0021 seconds for primes < 100000
>>> 0.0204 seconds for primes < 1000000
>>> 0.2389 seconds for primes < 10000000
>>> 2.6702 seconds for primes < 100000000
【讨论】:
【参考方案2】:我在 Willy Good 的评论中发现了一个纯 Python 2 素数生成器 here ,它比 rwh2_primes 更快。
def primes235(limit):
yield 2; yield 3; yield 5
if limit < 7: return
modPrms = [7,11,13,17,19,23,29,31]
gaps = [4,2,4,2,4,6,2,6,4,2,4,2,4,6,2,6] # 2 loops for overflow
ndxs = [0,0,0,0,1,1,2,2,2,2,3,3,4,4,4,4,5,5,5,5,5,5,6,6,7,7,7,7,7,7]
lmtbf = (limit + 23) // 30 * 8 - 1 # integral number of wheels rounded up
lmtsqrt = (int(limit ** 0.5) - 7)
lmtsqrt = lmtsqrt // 30 * 8 + ndxs[lmtsqrt % 30] # round down on the wheel
buf = [True] * (lmtbf + 1)
for i in xrange(lmtsqrt + 1):
if buf[i]:
ci = i & 7; p = 30 * (i >> 3) + modPrms[ci]
s = p * p - 7; p8 = p << 3
for j in range(8):
c = s // 30 * 8 + ndxs[s % 30]
buf[c::p8] = [False] * ((lmtbf - c) // p8 + 1)
s += p * gaps[ci]; ci += 1
for i in xrange(lmtbf - 6 + (ndxs[(limit - 7) % 30])): # adjust for extras
if buf[i]: yield (30 * (i >> 3) + modPrms[i & 7])
我的结果:
$ time ./prime_rwh2.py 1e8
5761455 primes found < 1e8
real 0m3.201s
user 0m2.609s
sys 0m0.578s
$ time ./prime_wheel.py 1e8
5761455 primes found < 1e8
real 0m2.710s
user 0m2.469s
sys 0m0.219s
...在我最近在 Win 10 上运行 Ubuntu 的中端笔记本电脑(i5 8265U 1.6GHz)上。
这是一个 mod 30 轮筛,它跳过了 2、3 和 5 的倍数。当我的笔记本电脑开始用完 8G RAM 并进行大量交换时,它对我来说效果很好,直到大约 2.5e9。
我喜欢 mod 30,因为它只有 8 个不是 2、3 或 5 的倍数的余数。这使得可以使用移位和“&”进行乘法、除法和 mod,并且应该允许对一个 mod 30 的结果进行打包轮到一个字节。我已将 Willy 的代码变形为分段式 mod 30 轮筛,以消除大 N 的颠簸,并将其发布到 here。
还有一个更快的javascript version,它是由@GordonBGood 分段并使用mod 210 轮(不是2、3、5 或7 的倍数),并提供对我有用的深入解释。
【讨论】:
【参考方案3】:我发现的最简单的方法是:
primes = []
for n in range(low, high + 1):
if all(n % i for i in primes):
primes.append(n)
【讨论】:
【参考方案4】:我已经更新了 Python 3 的大部分代码,并将其提交给 perfplot(我的一个项目),看看哪个实际上是最快的。事实证明,对于大的n
,primesfrom2,3to
占了上风:
重现情节的代码:
import perfplot
from math import sqrt, ceil
import numpy as np
import sympy
def rwh_primes(n):
# https://***.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Returns a list of primes < n """
sieve = [True] * n
for i in range(3, int(n ** 0.5) + 1, 2):
if sieve[i]:
sieve[i * i::2 * i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
return [2] + [i for i in range(3, n, 2) if sieve[i]]
def rwh_primes1(n):
# https://***.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Returns a list of primes < n """
sieve = [True] * (n // 2)
for i in range(3, int(n ** 0.5) + 1, 2):
if sieve[i // 2]:
sieve[i * i // 2::i] = [False] * ((n - i * i - 1) // (2 * i) + 1)
return [2] + [2 * i + 1 for i in range(1, n // 2) if sieve[i]]
def rwh_primes2(n):
# https://***.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
"""Input n>=6, Returns a list of primes, 2 <= p < n"""
assert n >= 6
correction = n % 6 > 1
n = 0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1[n % 6]
sieve = [True] * (n // 3)
sieve[0] = False
for i in range(int(n ** 0.5) // 3 + 1):
if sieve[i]:
k = 3 * i + 1 | 1
sieve[((k * k) // 3)::2 * k] = [False] * (
(n // 6 - (k * k) // 6 - 1) // k + 1
)
sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = [False] * (
(n // 6 - (k * k + 4 * k - 2 * k * (i & 1)) // 6 - 1) // k + 1
)
return [2, 3] + [3 * i + 1 | 1 for i in range(1, n // 3 - correction) if sieve[i]]
def sieve_wheel_30(N):
# http://zerovolt.com/?p=88
""" Returns a list of primes <= N using wheel criterion 2*3*5 = 30
Copyright 2009 by zerovolt.com
This code is free for non-commercial purposes, in which case you can just leave this comment as a credit for my work.
If you need this code for commercial purposes, please contact me by sending an email to: info [at] zerovolt [dot] com."""
__smallp = (
2,
3,
5,
7,
11,
13,
17,
19,
23,
29,
31,
37,
41,
43,
47,
53,
59,
61,
67,
71,
73,
79,
83,
89,
97,
101,
103,
107,
109,
113,
127,
131,
137,
139,
149,
151,
157,
163,
167,
173,
179,
181,
191,
193,
197,
199,
211,
223,
227,
229,
233,
239,
241,
251,
257,
263,
269,
271,
277,
281,
283,
293,
307,
311,
313,
317,
331,
337,
347,
349,
353,
359,
367,
373,
379,
383,
389,
397,
401,
409,
419,
421,
431,
433,
439,
443,
449,
457,
461,
463,
467,
479,
487,
491,
499,
503,
509,
521,
523,
541,
547,
557,
563,
569,
571,
577,
587,
593,
599,
601,
607,
613,
617,
619,
631,
641,
643,
647,
653,
659,
661,
673,
677,
683,
691,
701,
709,
719,
727,
733,
739,
743,
751,
757,
761,
769,
773,
787,
797,
809,
811,
821,
823,
827,
829,
839,
853,
857,
859,
863,
877,
881,
883,
887,
907,
911,
919,
929,
937,
941,
947,
953,
967,
971,
977,
983,
991,
997,
)
# wheel = (2, 3, 5)
const = 30
if N < 2:
return []
if N <= const:
pos = 0
while __smallp[pos] <= N:
pos += 1
return list(__smallp[:pos])
# make the offsets list
offsets = (7, 11, 13, 17, 19, 23, 29, 1)
# prepare the list
p = [2, 3, 5]
dim = 2 + N // const
tk1 = [True] * dim
tk7 = [True] * dim
tk11 = [True] * dim
tk13 = [True] * dim
tk17 = [True] * dim
tk19 = [True] * dim
tk23 = [True] * dim
tk29 = [True] * dim
tk1[0] = False
# help dictionary d
# d[a , b] = c ==> if I want to find the smallest useful multiple of (30*pos)+a
# on tkc, then I need the index given by the product of [(30*pos)+a][(30*pos)+b]
# in general. If b < a, I need [(30*pos)+a][(30*(pos+1))+b]
d =
for x in offsets:
for y in offsets:
res = (x * y) % const
if res in offsets:
d[(x, res)] = y
# another help dictionary: gives tkx calling tmptk[x]
tmptk = 1: tk1, 7: tk7, 11: tk11, 13: tk13, 17: tk17, 19: tk19, 23: tk23, 29: tk29
pos, prime, lastadded, stop = 0, 0, 0, int(ceil(sqrt(N)))
# inner functions definition
def del_mult(tk, start, step):
for k in range(start, len(tk), step):
tk[k] = False
# end of inner functions definition
cpos = const * pos
while prime < stop:
# 30k + 7
if tk7[pos]:
prime = cpos + 7
p.append(prime)
lastadded = 7
for off in offsets:
tmp = d[(7, off)]
start = (
(pos + prime)
if off == 7
else (prime * (const * (pos + 1 if tmp < 7 else 0) + tmp)) // const
)
del_mult(tmptk[off], start, prime)
# 30k + 11
if tk11[pos]:
prime = cpos + 11
p.append(prime)
lastadded = 11
for off in offsets:
tmp = d[(11, off)]
start = (
(pos + prime)
if off == 11
else (prime * (const * (pos + 1 if tmp < 11 else 0) + tmp)) // const
)
del_mult(tmptk[off], start, prime)
# 30k + 13
if tk13[pos]:
prime = cpos + 13
p.append(prime)
lastadded = 13
for off in offsets:
tmp = d[(13, off)]
start = (
(pos + prime)
if off == 13
else (prime * (const * (pos + 1 if tmp < 13 else 0) + tmp)) // const
)
del_mult(tmptk[off], start, prime)
# 30k + 17
if tk17[pos]:
prime = cpos + 17
p.append(prime)
lastadded = 17
for off in offsets:
tmp = d[(17, off)]
start = (
(pos + prime)
if off == 17
else (prime * (const * (pos + 1 if tmp < 17 else 0) + tmp)) // const
)
del_mult(tmptk[off], start, prime)
# 30k + 19
if tk19[pos]:
prime = cpos + 19
p.append(prime)
lastadded = 19
for off in offsets:
tmp = d[(19, off)]
start = (
(pos + prime)
if off == 19
else (prime * (const * (pos + 1 if tmp < 19 else 0) + tmp)) // const
)
del_mult(tmptk[off], start, prime)
# 30k + 23
if tk23[pos]:
prime = cpos + 23
p.append(prime)
lastadded = 23
for off in offsets:
tmp = d[(23, off)]
start = (
(pos + prime)
if off == 23
else (prime * (const * (pos + 1 if tmp < 23 else 0) + tmp)) // const
)
del_mult(tmptk[off], start, prime)
# 30k + 29
if tk29[pos]:
prime = cpos + 29
p.append(prime)
lastadded = 29
for off in offsets:
tmp = d[(29, off)]
start = (
(pos + prime)
if off == 29
else (prime * (const * (pos + 1 if tmp < 29 else 0) + tmp)) // const
)
del_mult(tmptk[off], start, prime)
# now we go back to top tk1, so we need to increase pos by 1
pos += 1
cpos = const * pos
# 30k + 1
if tk1[pos]:
prime = cpos + 1
p.append(prime)
lastadded = 1
for off in offsets:
tmp = d[(1, off)]
start = (
(pos + prime)
if off == 1
else (prime * (const * pos + tmp)) // const
)
del_mult(tmptk[off], start, prime)
# time to add remaining primes
# if lastadded == 1, remove last element and start adding them from tk1
# this way we don't need an "if" within the last while
if lastadded == 1:
p.pop()
# now complete for every other possible prime
while pos < len(tk1):
cpos = const * pos
if tk1[pos]:
p.append(cpos + 1)
if tk7[pos]:
p.append(cpos + 7)
if tk11[pos]:
p.append(cpos + 11)
if tk13[pos]:
p.append(cpos + 13)
if tk17[pos]:
p.append(cpos + 17)
if tk19[pos]:
p.append(cpos + 19)
if tk23[pos]:
p.append(cpos + 23)
if tk29[pos]:
p.append(cpos + 29)
pos += 1
# remove exceeding if present
pos = len(p) - 1
while p[pos] > N:
pos -= 1
if pos < len(p) - 1:
del p[pos + 1 :]
# return p list
return p
def sieve_of_eratosthenes(n):
"""sieveOfEratosthenes(n): return the list of the primes < n."""
# Code from: <dickinsm@gmail.com>, Nov 30 2006
# http://groups.google.com/group/comp.lang.python/msg/f1f10ced88c68c2d
if n <= 2:
return []
sieve = list(range(3, n, 2))
top = len(sieve)
for si in sieve:
if si:
bottom = (si * si - 3) // 2
if bottom >= top:
break
sieve[bottom::si] = [0] * -((bottom - top) // si)
return [2] + [el for el in sieve if el]
def sieve_of_atkin(end):
"""return a list of all the prime numbers <end using the Sieve of Atkin."""
# Code by Steve Krenzel, <Sgk284@gmail.com>, improved
# Code: https://web.archive.org/web/20080324064651/http://krenzel.info/?p=83
# Info: http://en.wikipedia.org/wiki/Sieve_of_Atkin
assert end > 0
lng = (end - 1) // 2
sieve = [False] * (lng + 1)
x_max, x2, xd = int(sqrt((end - 1) / 4.0)), 0, 4
for xd in range(4, 8 * x_max + 2, 8):
x2 += xd
y_max = int(sqrt(end - x2))
n, n_diff = x2 + y_max * y_max, (y_max << 1) - 1
if not (n & 1):
n -= n_diff
n_diff -= 2
for d in range((n_diff - 1) << 1, -1, -8):
m = n % 12
if m == 1 or m == 5:
m = n >> 1
sieve[m] = not sieve[m]
n -= d
x_max, x2, xd = int(sqrt((end - 1) / 3.0)), 0, 3
for xd in range(3, 6 * x_max + 2, 6):
x2 += xd
y_max = int(sqrt(end - x2))
n, n_diff = x2 + y_max * y_max, (y_max << 1) - 1
if not (n & 1):
n -= n_diff
n_diff -= 2
for d in range((n_diff - 1) << 1, -1, -8):
if n % 12 == 7:
m = n >> 1
sieve[m] = not sieve[m]
n -= d
x_max, y_min, x2, xd = int((2 + sqrt(4 - 8 * (1 - end))) / 4), -1, 0, 3
for x in range(1, x_max + 1):
x2 += xd
xd += 6
if x2 >= end:
y_min = (((int(ceil(sqrt(x2 - end))) - 1) << 1) - 2) << 1
n, n_diff = ((x * x + x) << 1) - 1, (((x - 1) << 1) - 2) << 1
for d in range(n_diff, y_min, -8):
if n % 12 == 11:
m = n >> 1
sieve[m] = not sieve[m]
n += d
primes = [2, 3]
if end <= 3:
return primes[: max(0, end - 2)]
for n in range(5 >> 1, (int(sqrt(end)) + 1) >> 1):
if sieve[n]:
primes.append((n << 1) + 1)
aux = (n << 1) + 1
aux *= aux
for k in range(aux, end, 2 * aux):
sieve[k >> 1] = False
s = int(sqrt(end)) + 1
if s % 2 == 0:
s += 1
primes.extend([i for i in range(s, end, 2) if sieve[i >> 1]])
return primes
def ambi_sieve_plain(n):
s = list(range(3, n, 2))
for m in range(3, int(n ** 0.5) + 1, 2):
if s[(m - 3) // 2]:
for t in range((m * m - 3) // 2, (n >> 1) - 1, m):
s[t] = 0
return [2] + [t for t in s if t > 0]
def sundaram3(max_n):
# https://***.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/2073279#2073279
numbers = range(3, max_n + 1, 2)
half = (max_n) // 2
initial = 4
for step in range(3, max_n + 1, 2):
for i in range(initial, half, step):
numbers[i - 1] = 0
initial += 2 * (step + 1)
if initial > half:
return [2] + filter(None, numbers)
# Using Numpy:
def ambi_sieve(n):
# http://tommih.blogspot.com/2009/04/fast-prime-number-generator.html
s = np.arange(3, n, 2)
for m in range(3, int(n ** 0.5) + 1, 2):
if s[(m - 3) // 2]:
s[(m * m - 3) // 2::m] = 0
return np.r_[2, s[s > 0]]
def primesfrom3to(n):
# https://***.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Returns an array of primes, p < n """
assert n >= 2
sieve = np.ones(n // 2, dtype=bool)
for i in range(3, int(n ** 0.5) + 1, 2):
if sieve[i // 2]:
sieve[i * i // 2::i] = False
return np.r_[2, 2 * np.nonzero(sieve)[0][1::] + 1]
def primesfrom2to(n):
# https://***.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Input n>=6, Returns an array of primes, 2 <= p < n """
assert n >= 6
sieve = np.ones(n // 3 + (n % 6 == 2), dtype=bool)
sieve[0] = False
for i in range(int(n ** 0.5) // 3 + 1):
if sieve[i]:
k = 3 * i + 1 | 1
sieve[((k * k) // 3)::2 * k] = False
sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = False
return np.r_[2, 3, ((3 * np.nonzero(sieve)[0] + 1) | 1)]
def sympy_sieve(n):
return list(sympy.sieve.primerange(1, n))
b = perfplot.bench(
setup=lambda n: n,
kernels=[
rwh_primes,
rwh_primes1,
rwh_primes2,
sieve_wheel_30,
sieve_of_eratosthenes,
sieve_of_atkin,
# ambi_sieve_plain,
# sundaram3,
ambi_sieve,
primesfrom3to,
primesfrom2to,
sympy_sieve,
],
n_range=[2 ** k for k in range(3, 25)],
xlabel="n",
)
b.save("out.png")
b.show()
【讨论】:
嗯,对数图... :)【参考方案5】:这是问题中解决方案的变体,应该比问题中的解决方案更快。它使用 Eratosthenes 的静态筛子,没有其他优化。
from typing import List
def list_primes(limit: int) -> List[int]:
primes = set(range(2, limit + 1))
for i in range(2, limit + 1):
if i in primes:
primes.difference_update(set(list(range(i, limit + 1, i))[1:]))
return sorted(primes)
>>> list_primes(100)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
【讨论】:
【参考方案6】:对于较大的 n 值,这是迄今为止最快的解决方案(至少在我的机器上)。它同时使用 numpy 和 bitarray,并受到来自 this answer 的 primesfrom2to
的启发。在我的机器上,n
的值超过约 1.5 亿会更快。
import numpy as np
from bitarray import bitarray
def bit_primes(n):
bit_sieve = bitarray(n // 3 + (n % 6 == 2))
bit_sieve.setall(1)
bit_sieve[0] = False
for i in range(int(n ** 0.5) // 3 + 1):
if bit_sieve[i]:
k = 3 * i + 1 | 1
bit_sieve[k * k // 3::2 * k] = False
bit_sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = False
np_sieve = np.unpackbits(np.frombuffer(bit_sieve.tobytes(), dtype=np.uint8)).astype(np.bool, copy=False)
return np.concatenate(((2, 3), ((3 * np.flatnonzero(np_sieve) + 1) | 1)))
这是与primesfrom2to
的比较:
python3.9 -m timeit -s "import fast_primes" "fast_primes.bit_primes(500_000_000)"
1 loop, best of 5: 1.22 sec per loop
python3.9 -m timeit -s "import fast_primes" "fast_primes.primesfrom2to(500_000_000)"
1 loop, best of 5: 1.95 sec per loop
作为参考,这是我用来比较的primesfrom2to
的最小修改(在 Python 3 中工作)版本:
def primesfrom2to(n):
# https://***.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Input n>=6, Returns a array of primes, 2 <= p < n"""
sieve = np.ones(n // 3 + (n % 6 == 2), dtype=np.bool)
sieve[0] = False
for i in range(int(n ** 0.5) // 3 + 1):
if sieve[i]:
k = 3 * i + 1 | 1
sieve[((k * k) // 3)::2 * k] = False
sieve[(k * k + 4 * k - 2 * k * (i & 1)) // 3::2 * k] = False
return np.r_[2, 3, ((3 * np.nonzero(sieve)[0] + 1) | 1)]
【讨论】:
【参考方案7】:您有更快的代码和最简单的代码生成素数。
但是对于更高的数字,它不适用于 n=10000, 10000000
它失败了,可能是 .pop()
方法
考虑:N 是素数吗?
案例一:
你得到了 N 的一些因数,
for i in range(2, N):
如果 N 是素数,则循环执行 ~(N-2) 次。 else 减少次数
案例2:
for i in range(2, int(math.sqrt(N)):
如果 N 是素数,则循环执行大约 ~(sqrt(N)-2) 次,否则会在某处中断
案例3:
我们最好将 N 除以 素数
循环仅执行 π(sqrt(N)) 次
π(sqrt(N))
from math import sqrt
from time import *
prime_list = [2]
n = int(input())
s = time()
for n0 in range(2,n+1):
for i0 in prime_list:
if n0%i0==0:
break
elif i0>=int(sqrt(n0)):
prime_list.append(n0)
break
e = time()
print(e-s)
#print(prime_list); print(f'pi(n)=len(prime_list)')
print(f'n: len(prime_list), time: e-s')
输出
100: 25, time: 0.00010275840759277344
1000: 168, time: 0.0008606910705566406
10000: 1229, time: 0.015588521957397461
100000: 9592, time: 0.023436546325683594
1000000: 78498, time: 4.1965954303741455
10000000: 664579, time: 109.24591708183289
100000000: 5761455, time: 2289.130858898163
小于 1000 似乎很慢,但对于
不过,我无法理解时间复杂度。
【讨论】:
以上是关于列出 N 以下所有素数的最快方法的主要内容,如果未能解决你的问题,请参考以下文章