Prima di tutto, mod
è lento in modo da utilizzare rem
in situazioni in cui non importa (quando non si tratta di aspetti negativi, in fondo). In secondo luogo, utilizzare Criterion per mostrare (a se stessi) ciò che è più veloce e quali cambiamenti sono in realtà le ottimizzazioni. So che non sto dando una risposta completa per mettere in discussione con questo, ma è un buon posto per voi (e altri answerers potenziali) di avviare, quindi ecco qualche codice:
import List
import Criterion.Main
main = do
str <- getLine
let run f = length . f
input = read str :: Integer
defaultMain [ bench "primes" (nf (run primes) input)
, bench "primes'" (nf (run primes') input)
, bench "primes''" (nf (run primes'') input)
, bench "primesTMD" (nf (run primesTMD) input)
, bench "primes'TMD" (nf (run primes'TMD) input)
, bench "primes''TMD" (nf (run primes''TMD) input)
]
putStrLn . show . length . primes'' $ (read str :: Integer)
-- primeira implementação
primes n
| n < 2 = []
| n == 2 = [2]
| n `mod` 2 == 0 = primes'
| otherwise = if (find (\x -> n `mod` x == 0) primes') == Nothing then
n:primes'
else
primes'
where primes' = primes (n - 1)
primesTMD n
| n < 2 = []
| n == 2 = [2]
| n `mod` 2 == 0 = primes'
| otherwise = if (find (\x -> n `rem` x == 0) primes') == Nothing then
n:primes'
else
primes'
where primes' = primesTMD (n - 1)
-- segunda implementação
primes' :: Integer -> [Integer]
primes' n = sieve $ 2 : [3,5..n]
where sieve :: [Integer] -> [Integer]
sieve [] = []
sieve [email protected](x:xs)
| x*x >= n = l
| otherwise = x : sieve list'
where list' = filter (\y -> y `mod` x /= 0) xs
primes'TMD :: Integer -> [Integer]
primes'TMD n = sieve $ 2 : [3,5..n]
where sieve :: [Integer] -> [Integer]
sieve [] = []
sieve [email protected](x:xs)
| x*x >= n = l
| otherwise = x : sieve list'
where list' = filter (\y -> y `rem` x /= 0) xs
-- terceira implementação
primes'' :: Integer -> [Integer]
primes'' n = 2 : sieve 3 [3,5..n]
where sieve :: Integer -> [Integer] -> [Integer]
sieve _ [] = []
sieve m [email protected](x:xs)
| m*m >= n = l
| x < m*m = x : sieve m xs
| otherwise = sieve (m + 2) list'
where list'= filter (\y -> y `mod` m /= 0) l
primes''TMD :: Integer -> [Integer]
primes''TMD n = 2 : sieve 3 [3,5..n]
where sieve :: Integer -> [Integer] -> [Integer]
sieve _ [] = []
sieve m [email protected](x:xs)
| m*m >= n = l
| x < m*m = x : sieve m xs
| otherwise = sieve (m + 2) list'
where list'= filter (\y -> y `rem` m /= 0) l
Avviso la migliore esecuzione del varianti usando rem
:
$ ghc --make -O2 sieve.hs
$./sieve
5000
...
benchmarking primes
mean: 23.88546 ms, lb 23.84035 ms, ub 23.95000 ms
benchmarking primes'
mean: 775.9981 us, lb 775.4639 us, ub 776.7081 us
benchmarking primes''
mean: 837.7901 us, lb 836.7824 us, ub 839.0260 us
benchmarking primesTMD
mean: 16.15421 ms, lb 16.11955 ms, ub 16.19202 ms
benchmarking primes'TMD
mean: 568.9857 us, lb 568.5819 us, ub 569.4641 us
benchmarking primes''TMD
mean: 642.5665 us, lb 642.0495 us, ub 643.4105 us
Mentre vedo che si sta facendo questo per il tuo formazione, la sua pena di notare i link correlati di Primes on Haskell.org e il digiuno Primes package su hackage.
fonte
2010-10-04 04:39:43
1) Il tuo inglese va bene. 2) Mi piace davvero che tu abbia allegato un codice eseguibile - così poche domande lo fanno ultimamente. 3) Potresti anche includere il tuo comando di compilazione - alcune persone dimenticano -O2 (e una volta un esperimento -O3 esisteva e rallentava molti programmi ma i nuovi arrivati non lo sapevano). –
Potresti essere interessato al documento [The Genuine Sieve of Eratosthenes] (http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf). Copre diverse implementazioni (incluso un finto setaccio) e parla delle caratteristiche di base delle prestazioni e offre alcuni modi per accelerare l'algoritmo. –
Uno dei messaggi importanti del documento "Il vero setaccio di Eratostene" è che, sebbene i codici come questi tre siano spesso forniti come "implementazioni del setaccio di Eratostene", le loro prestazioni sono più vicine a quelle dell'algoritmo di divisione di prova (lento) rispetto a quello del setaccio di Eratostene (veloce). –