我找到了一个"奇怪的"这里的行为。我明白了:
{-# LANGUAGE BangPatterns #-}
import Data.List
import Control.Parallel
import Control.Parallel.Strategies
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
main =
let xs = [ fib (20 + n `mod` 2) | n <- [0..1000] ]
`using` test rseq
in print (sum xs)
test :: Strategy a -> Strategy [a]
test strat xs = do
parTraversable strat xs -- case #1
-- parList strat xs -- case #2
return xs
case #1
表示使用parTraversable
,case #2
表示使用parList
。结果不同:
case #1: SPARKS: 1001 (1 converted, 0 overflowed, 0 dud, 1000 GC'd, 0 fizzled)
case #2: SPARKS: 1001 (1000 converted, 0 overflowed, 0 dud, 0 GC'd, 1 fizzled)
据我所知,parList
与parTraversable
相同。在Control/Parallel/Strategies.hs
:
parTraversable :: Traversable t => Strategy a -> Strategy (t a)
parTraversable strat = evalTraversable (rparWith strat)
parList :: Strategy a -> Strategy [a]
parList = parTraversable
所以我认为他们必须采取同样的行动。有什么需要在这里发现吗?
更新#1 :
编译和运行的命令:
stack ghc -- -O2 -threaded -rtsopts -eventlog parlist2.hs
./parList2 +RTS -N2 -s