ant*_*kos 5 io closures haskell inlining ghc
我有一个过程,(a)做一些IO,(b)构造一个查找表,(c)返回一个使用查找表的IO动作.但是在编译时-O
,GHC(版本6.12.1)内联构建查找表,以便在每次调用IO操作时重新评估它.
例:
module Main where
import Data.Array
import Data.IORef
import Control.Monad
makeAction getX getY sumRef = do
x <- getX
let a = listArray (0, 1000) [x ..]
return $ do
y <- getY
modifyIORef sumRef (\sum -> sum + a ! y)
main = do
sumRef <- newIORef 0
action <- makeAction getX getY sumRef
replicateM_ 100000 action
n <- readIORef sumRef
putStrLn (show n)
where
getX = return (1 :: Int)
getY = return 0
Run Code Online (Sandbox Code Playgroud)
这个问题是众所周知的,有足够的标准GHC万无一失的解决方法 - 或者你如何调整程序,以免a
重复分配?
最简单的解决方法是使用严格注释强制评估。
{-# LANGUAGE BangPatterns #-}
Run Code Online (Sandbox Code Playgroud)
a
然后通过简单地使用(“bang”)进行严格强制分配!
。
let !a = listArray (0, 1000) [x ..]
Run Code Online (Sandbox Code Playgroud)
或者,如果您在 monad 中工作IO
,严格注释可能并不总是有帮助。IO
要在运行某些操作之前强制计算表达式,您可以使用evaluate
。例如:
let a = listArray (0, 1000) [x ..]
evaluate a
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
333 次 |
最近记录: |