2016-01-09 140 views
14

例如:当垃圾收集垃圾时,Haskell是否放弃了火花?

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

y火花停止,如果x丢弃计算(多)更快,是Just ...

为了更具体一些,我想搜索一个列表,但每个比较都非常昂贵。我想对搜索进行并行化处理,但是我希望一旦找到匹配项就可以放弃其余的比较结果。

回答

4

您的意思是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'd火花。

+0

是的,你纠正了我的错误,就像它应该是:),谢谢!所以我猜想终止任务我不得不求助于使用并发性并用'killThread'手动杀死线程。 –