我目前正在使用Haskell制作光线跟踪程序.由于我是Haskell的初学者,我不明白IO monad的评估策略.
问题是一长串"IO a"的内存使用情况,在我的代码中是"IO Vec".
列表的每个元素由递归函数计算IO Vec,该函数计算表示像素的颜色.因此,列表的长度等于width x height.
另外,我为像素拍摄了多个样本.总的来说,radiance计算像素值的函数称为width x height x samples时间.
首先,我只是通过使用列表理解来实现这个程序.代码就像,
main = do
...
let ray = (compute ray for every pair of [0..w-1], [0..h-1]
pixels <- sequence [ (sumOfRadiance scene ray samples) | ray <- rays]
Run Code Online (Sandbox Code Playgroud)
在我的理解中,由于在将像素写入文件之前未使用像素,因此Haskell存储一些用于函数调用的数据,pixels其中是一个数组IO Vec.最后,通过调用递归函数radiance来计算像素值,可以增加内存消耗.
如果我改变程序来逐个评估像素值,unsafePerformIO可以防止这种奇怪的使用内存空间.
main = do
...
let ray = (compute ray for every pair of [0..w-1], [0..h-1]
let pixels = [ …Run Code Online (Sandbox Code Playgroud) haskell ×1