Posłużyłem się równoległymi funkcjami Haskella par
i pseq
i odkryłem coś interesującego.Równoległa lista wydajności Haskella
Moja baza przykładów na przykłady z książki Real World Haskell „s (Parallel programming in Haskell):
wspólny kod:
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]
sortowania kod 1 (zaczerpnięte z książki):
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 _ = []
kod sortowania 2 (mój zwyczaj wariant):
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 _ = []
kompilacji & prowadzony z: ghc -O2 -threaded --make Main.hs && time ./Main +RTS -N8
Co ciekawe, mój wariant jest nieco szybciej niż książek One:
sorting code 1 - avg. 16 seconds
sorting code 2 - avg. 14 seconds
chcę zapytaj, dlaczego obserwujemy takie zachowanie i czy rozwiązanie książki daje jakiekolwiek korzyści w stosunku do mojej. Bardzo chciałbym zrozumieć, dlaczego to rozwiązanie może działać lepiej.