当垃圾收集垃圾时,Haskell是否放弃了火花?
问题描述:
x :: Maybe a
y :: a
y `par` x `pseq` (fromMaybe y x)
是y
火花停止,如果x
丢弃计算(多)更快,是Just ...
?
为了更具体一些,我想搜索一个列表,但每个比较都非常昂贵。我想对搜索进行并行化处理,但是我希望一旦找到匹配项就可以放弃其余的比较结果。
答
您的意思是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火花。
是的,你纠正了我的错误,就像它应该是:),谢谢!所以我猜想终止任务我不得不求助于使用并发性并用'killThread'手动杀死线程。 –