我在Haskell中尝试并行和并发,并提出了这个问题。我有2个函数来并行计算列表的每个元素:
parMap' :: (a -> b) -> [a] -> Eval [b]
parMap' f [] = return []
parMap' f (a:as) = do
b <- rpar (f a)
bs <- parMap' f as
return (b:bs)
parListWHNF :: Strategy [a]
parListWHNF xs = go xs `pseq` return xs
where -- go :: [a] -> [a]
go [] = []
go (y:ys) = y `par` go ys
如果我直接使用它们,一切都很好(所有火花都被转换):
let solutions = runEval (parMap' solve puzzles)
result: SPARKS: 1000 (1000 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
let solutions = map solve puzzles `using` parListWHNF
result: SPARKS: 1000 (1000 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)
但是如果我将它们包装在另一个函数中:
parList' :: (NFData a) => Strategy a -> Strategy [a]
parList' strat xs = do
parMap' id xs -- case #1
-- parListWHNF xs -- case #2
return xs
let solutions = map solve puzzles `using` parList' rseq
然后,只有case #2
有效(所有火花都被转换),case #1
会产生很多火花GC&#39; d:
SPARKS: 1000 (3 converted, 0 overflowed, 0 dud, 997 GC'd, 0 fizzled)
任何人都可以解释这个PLZ吗?