I've wrote simple Haskell benchmark program, which populated primitive vector from vector package:
import Data.Vector.Primitive.Mutable as P
vectorBench :: Benchmark
vectorBench = bgroup "vector" [ primitive ]
where
primitive = bgroup "primitive" [ write1M ]
where
write1M = bench "write1M" $ nfIO $ do
v <- P.unsafeNew 1000000
void $ for [0..1000000 - 1] $ flip (P.unsafeWrite v) (1 :: Int)
return ()
I use `unsafeNew` to skip memory initialization and `unsafeWrite` to skip boundary checks, I guess it's fastest possible way to write something to vector. My result was about 40 ms.
I wrote similar program in Scala:
for (_ <- 1 to 5) {
val start = System.currentTimeMillis()
val a = new Array[Long](1000000)
for (i <- 0 until 1000000) {
a(i) = 1L
}
val end = System.currentTimeMillis()
println(s"${end - start} ms")
}
I skip neither boundary checks nor memory initialization, I also used generic array here (suitable for any types of objects, not just for primitive types), so I expected longer run time. But what I got was shocking:
7 ms
3 ms
2 ms
1 ms
2 ms
This program runs 20-40 times faster than Haskell after warm-up. 20-40 times, Carl! Why is Haskell soo slooooow? How can it be?
--
Sincerely, Stanislav Chernichkin.