这很慢,因为该算法是一个不停留在平方根的试除法。
如果您仔细观察算法的作用,您会发现对于每个素数 p,其不具有较小素因数的倍数将从候选列表中删除(具有较小素因数的倍数先前已被删除)。
所以每个数字都被所有素数除,直到它作为其最小素数除数的倍数被删除,或者如果它是素数,它出现在剩余候选者列表的头部。
对于合数来说,这并不是特别糟糕,因为大多数合数都有小的素数除数,在最坏的情况下,n 的最小素数除数不会超过√n。
但是素数被所有个较小的素数除,所以直到第k个素数被发现是素数,它已经被所有k-1个较小的素数除.如果有m 质数低于限制n,则找到所有质数所需的工作是
(1-1) + (2-1) + (3-1) + ... + (m-1) = m*(m-1)/2
部门。通过Prime number theorem,n 以下的素数数量渐近为n / log n(其中log 表示自然对数)。消除复合材料的工作可以粗略地受到n * √n 除法的限制,因此对于不太小的n,与在素数上花费的工作相比可以忽略不计。
对于 200 万的素数,特纳筛需要大约 1010 格。此外,它还需要对大量列表单元进行解构和重构。
止于平方根的试除法,
isPrime n = go 2
where
go d
| d*d > n = True
| n `rem` d == 0 = False
| otherwise = go (d+1)
primes = filter isPrime [2 .. ]
需要少于 1.9*109 个除法(粗略估计,如果 每个 isPrime n 检查到 √n - 实际上,它只需要 179492732,因为复合材料是一般便宜)(1) 和更少的列表操作。此外,通过跳过偶数(2 除外)作为候选除数,可以轻松改进此试验除数,从而将所需除数减半。
Eratosthenes 的筛子不需要任何除法,只使用O(n * log (log n)) 操作,这要快很多:
primeSum.hs:
module Main (main) where
import System.Environment (getArgs)
import Math.NumberTheory.Primes
main :: IO ()
main = do
args <- getArgs
let lim = case args of
(a:_) -> read a
_ -> 1000000
print . sum $ takeWhile (<= lim) primes
并以 1000 万的限制运行它:
$ ghc -O2 primeSum && time ./primeSum 10000000
[1 of 1] Compiling Main ( primeSum.hs, primeSum.o )
Linking primeSum ...
3203324994356
real 0m0.085s
user 0m0.084s
sys 0m0.000s
我们让试用部门只跑到100万(固定类型为Int):
$ ghc -O2 tdprimeSum && time ./tdprimeSum 1000000
[1 of 1] Compiling Main ( tdprimeSum.hs, tdprimeSum.o )
Linking tdprimeSum ...
37550402023
real 0m0.768s
user 0m0.765s
sys 0m0.002s
而特纳筛子只到 100000:
$ ghc -O2 tuprimeSum && time ./tuprimeSum 100000
[1 of 1] Compiling Main ( tuprimeSum.hs, tuprimeSum.o )
Linking tuprimeSum ...
454396537
real 0m2.712s
user 0m2.703s
sys 0m0.005s
(1)粗略估计是
2000000
∑ √k ≈ 4/3*√2*10^9
k = 1
计算为两位有效数字。由于大多数数字是具有小素因数的复合数 - 一半的数字是偶数并且只需要一个除法 - 这大大高估了所需的除法数。
仅考虑素数即可获得所需除法数的下限:
∑ √p ≈ 2/3*N^1.5/log N
p < N
p prime
对于N = 2000000,大约为 1.3*108。这是正确的数量级,但低估了一个重要的因素(对于增长的N,缓慢减少到 1,对于N > 10,永远不会超过 2)。
除了素数之外,素数的平方和两个相近素数的乘积也需要试除法(几乎)上升到√k,因此如果有足够多的数,则对整体工作有很大贡献。
但是,处理半素数所需的除法数受 的常数倍数的限制
N^1.5/(log N)^2
所以对于非常大的N,它相对于处理素数的成本变得可以忽略不计。但在完全可行的试制范围内,它们的贡献仍然很大。