Haskell parallel list computation performance
I was plaing with parallel Haskell functions par and pseq and I have
discovered something interesting.
My examples base on the examples from Real World Haskell's book (Parallel
programming in Haskell):
common code:
import Control.Parallel (par, pseq)
-- <<sorting code goes here>>
force :: [a] -> ()
force xs = go xs `pseq` ()
where go (_:xs) = go xs
go [] = 1
main = do
print $ take 10 $ parSort [0..1000000]
sorting code 1 (taken from the book):
parSort :: (Ord a) => [a] -> [a]
parSort (x:xs) = force greater `par` (force lesser `pseq`
(lesser ++ x:greater))
where lesser = parSort [y | y <- xs, y < x]
greater = parSort [y | y <- xs, y >= x]
parSort _ = []
sorting code 2 (my custom variant):
parSort :: (Ord a) => [a] -> [a]
parSort (x:xs) = force greater `par` (lesser ++ x:greater)
where lesser = parSort [y | y <- xs, y < x]
greater = parSort [y | y <- xs, y >= x]
parSort _ = []
Compile & run with: ghc -O2 -threaded --make Main.hs && time ./Main +RTS -N8
What is interesting, my variant is a little faster than the books one:
sorting code 1 - avg. 16 seconds
sorting code 2 - avg. 14 seconds
I want to ask you why we can observe such behavior and if the book's
solution gives any benefits over mine. I would love to deeply understand
why this solution could perform better.
No comments:
Post a Comment