This is very slow because the algorithm is a test division that does not stop at the square root.
If you carefully look at what the algorithm does, you will see that for each prime pits multiples that do not have smaller prime divisors are removed from the list of candidates (multiples with smaller simply divisors were removed earlier).
, , , .
, , n √n.
, , k th k-1 . m n, , ,
(1-1) + (2-1) + (3-1) + ... + (m-1) = m*(m-1)/2
. n n / log n ( log ). n * √n, n, , .
, , 10 10 . , .
, ,
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 * 10 9 ( , 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
10 :
$ 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
1 ( 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
Turner 100 000:
$ 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 * 10 8. , ( 1 n 2 N > 10).
, , () √k , , , .
, , ,
N^1.5/(log N)^2
n . , , - .