我一直在尝试在 Haskell 中编码一个需要使用大量可变引用的算法,但与纯粹的惰性代码相比,它(也许并不奇怪)非常慢。考虑一个非常简单的例子:
module Main where
import Data.IORef
import Control.Monad
import Control.Monad.Identity
list :: [Int]
list = [1..10^6]
main1 = mapM newIORef list >>= mapM readIORef >>= print
main2 = print $ map runIdentity $ map Identity list
在我的机器上运行 GHC 7.8.2,main1
耗时 1.2 秒,使用 290MB 内存,而main2
仅耗时 0.4 秒,仅使用 1MB。有什么技巧可以防止这种增长,尤其是在太空中?我经常需要IORef
s 来表示与 不同的非原始类型Int
,并假设 anIORef
会像常规 thunk 一样使用附加指针,但我的直觉似乎是错误的。
我已经尝试过使用 unpacked 的特殊列表类型IORef
,但没有显着差异。