I wrote the classic prime number sieve algorithm in C which pretty much instantly generates all the primes smaller than 1,000,000 on my machine (I didn't do anything to optimize it).
In Haskell I use a Vector
of Int
s, and generate an update list for each prime number which sets the multiples to zero. This is basically the same thing as I do in C with a nested for
loop:
import qualified Data.Vector.Unboxed as U
--| generate primes smaller than p
sievePrimes :: Int -> U.Vector Int
sievePrimes p = foldl f ns [0..p-1]
where
ns = U.fromList $ 0:[2..p]
f v i
| v U.! i == 0 = v
| otherwise = v U.// [((i + 1)*k - 1, 0) | k <- [2..p `div` (i + 1)]]
The Haskell version runs about 1000 times slower than the C version. All I've done to optimize is to use the vector
package. The algorithm is the same.
Why is it running so much slower? Isn't Vector
efficient enough?
I compiled both C and Haskell with -O2
.