我试图在Haskell中编写一个安全的超时评估函数。代码如下
import System.Timeout
compute, compute' :: Int -> Int
compute i = sum [1..300000 + i]
compute' i = last $ repeat i
timedComp :: Int -> a -> IO (Maybe a)
timedComp timeLeft toCompute =
timeout timeLeft go
where
go = toCompute `seq` return toCompute
main = do
res <- timedComp 10000 (compute 0)
print res
res' <- timedComp 10000 (compute' 0)
print res'
(我知道我只评估WHNF。)
当我运行main时,我只输出一个Nothing,然后程序挂起。我试图编译并运行程序多线程,但它没有帮助。试用GHC 7.6.3和7.8.3。有什么建议吗?
答案 0 :(得分:3)
Haskell线程的GHC实现存在限制:上下文切换仅在分配期间发生。因此,完全不执行分配的紧密循环可能会阻止调度程序运行,切换到其他线程。
这是其中一个例子:compute' i = last $ repeat i
看起来好像在分配列表单元格,但不幸的是GHC能够将其优化为一个无关紧要的循环,去除所有分配 - GHC Core看起来大致为{{1 }}。这会触发调度程序的缺点。
Reid Barton建议使用f x = f x
选项来解决这个问题。这将导致GHC不会如此优化。