# [Haskell-cafe] I killed performance of my code with Eval and Strategies

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

```