[Haskell-cafe] I killed performance of my code with Eval and Strategies
Bertram Felgenhauer
bertram.felgenhauer at googlemail.com
Sun Nov 18 02:41:21 CET 2012
Dear Janek,
> I am reading Simon Marlow's tutorial on parallelism and I have problems
> with correctly using Eval monad and Strategies. I *thought* I understand
> them but after writing some code it turns out that obviously I don't
> because parallelized code is about 20 times slower. Here's a short
> example (code + criterion benchmarks):
Actually, (sin . sqrt) is simply too cheap. The overhead of constructing
chunks (which have to be constructed on the heap) and concatenating the
results far outweighs the cost of computing the list elements.
If, for example, you replace sin . sqrt by f defined by
f :: Double -> Double
f x | x < 10 = x*x
| otherwise = sin x * f (x-100)
the picture will change. The loss also becomes far less dramatic if
you construct the chunks outside of the benchmark:
main :: IO ()
main = defaultMain [
bench "Seq" $ nf (map calculateSeq) xs
, bench "Par" $ nf calculatePar xs ]
where xs = chunk 2048 [1..16384]
f, f' :: Double -> Double
f x = sqrt (sin x)
f' x | x < 10 = x*x
| otherwise = sin x * f' (x-100)
calculateSeq :: [Double] -> [Double]
calculateSeq [] = []
calculateSeq (x:xs) = f x : calculateSeq xs
calculatePar :: [[Double]] -> [[Double]]
calculatePar xss = runEval $ parList (rdeepseq . calculateSeq) xss
chunk :: Int -> [a] -> [[a]]
chunk _ [] = []
chunk n xs = as : chunk n bs where !(as, bs) = splitAt n xs
The parallel version (with f = sqrt . sin) is still somewhat slower
than the sequential version with -N1 -- probably due to rdeepseq.
Best regards,
Bertram
More information about the Haskell-Cafe
mailing list