Finding primes using a primes map with Haskell and Hugs98
Hannah Schroeter
uk1o@rz.uni-karlsruhe.de
Thu, 18 Jan 2001 00:58:59 +0100
Hello!
On Wed, Dec 20, 2000 at 04:02:23PM +0200, Shlomi Fish wrote:
> [...]
> primes :: Int -> [Int]
> primes how_much = sieve [2..how_much] where
> sieve (p:x) =
> p : (if p <= mybound
> then sieve (remove (p*p) x)
> else x) where
> remove what (a:as) | what > how_much = (a:as)
> | a < what = a:(remove what as)
> | a == what = (remove (what+step) as)
> | a > what = a:(remove (what+step) as)
> remove what [] = []
> step = (if (p == 2) then p else (2*p))
> sieve [] = []
> mybound = ceiling(sqrt(fromIntegral how_much))
> [...]
How about this: Yet another infinite list version, however
only sieving numbers to the square of the current maximum:
primes :: [Int]
primes = 2:fil' 4 primes [3..]
where
fil' cutoff fl@(f:fs) rl@(r:rs) =
if r < cutoff then r:fil' cutoff fl rs
else fil' (square (head fs)) fs [y|y<-rl, (y `mod` f) /= 0]
square x = x*x
Comparison:
my version (with a small main around it):
hannah@mamba:~/src/haskell $ time ./primes 1000000 >/tmp/p1
real 0m31.928s
user 0m31.690s
sys 0m0.317s
your version (with adapted small main around it):
hannah@mamba:~/src/haskell $ time ./primes2 1000000 >/tmp/p2
real 0m42.993s
user 0m42.023s
sys 0m0.236s
(measurements with ghc 4.08, -O2 -O2-for-C, Pentium I 200 MHz 64 MB RAM)
The outputs (primes list + number of found primes) are the same.
In contrast, take the simple two-liner
primes :: [Int]
primes = p' [2..] where p' (p:ps) = p:p' [y|y<-ps, (y `mod` p) /= 0]
with the same small main:
hannah@mamba:~/src/haskell $ time ./primes0 100000 >/tmp/p0
real 2m17.460s
user 2m15.773s
sys 0m1.170s
(mine with 100000 limit)
hannah@mamba:~/src/haskell $ time ./primes 100000 >/tmp/p1
real 0m1.666s
user 0m1.607s
sys 0m0.048s
(yours with 100000 limit)
hannah@mamba:~/src/haskell $ time ./primes2 100000 >/tmp/p2
real 0m1.903s
user 0m1.827s
sys 0m0.064s
Kind regards,
Hannah.