当thunk被垃圾收集时,Haskell会丢弃火花吗?

时间:2016-01-09 19:12:10

标签: haskell parallel-processing ghc

例如:

x :: Maybe a
y :: a
y `par` x `pseq` (fromMaybe y x)

如果y计算得多x,那么Just ...的火花会停止并被丢弃吗?<{1}}

更具体地说,我想搜索一个列表,但每次比较都非常昂贵。我想要对搜索进行并行化,但是我希望在找到匹配项后将其余的比较放弃。

1 个答案:

答案 0 :(得分:5)

您的意思是fromMaybe而不是maybe吗?

x `par` y `pseq` (fromMaybe y x)

此外,您正在为评估x创建一个火花,而不是y。因此,在评估fromMaybe y x之前,不会评估y。可能你的意思恰恰相反:

y `par` x `pseq` (fromMaybe y x)

如果以上都是真的,那么您的问题的答案是“否”,火花将不会在已经启动时停止(尽管如果尚未启动它将被丢弃。)您可以使用以下测试进行检查:

import Data.Maybe
import Control.Concurrent
import Control.Parallel
import System.IO.Unsafe
import System.Mem

{-# NOINLINE x #-}
x = unsafePerformIO $ do
  threadDelay 1000
  return (Just 1)

{-# NOINLINE y #-}
y = unsafePerformIO $ do
  print "will eval y"
  threadDelay 3000000
  print "did eval y"
  return (2 :: Int)

main :: IO ()
main = do
  print $ y `par` x `pseq` fromMaybe y x
  print "done"
  performGC
  threadDelay 4000000

输出:

"will eval y"
1
"done"
"did eval y"

您还可以查看运行时统计信息+RTS -s。它包含许多GC的火花。