sda*_*das 7 optimization haskell
我正在编写一个程序来使用Haskell解析.TGA文件 - 但是,性能绝对可怕.2048 x 2048像素图像需要几秒钟才能解析.
我运行了我的代码+RTS -p -RTS
并收到了报告中的以下有趣内容:
total time = 1.08 secs
total alloc = 3,037,568,120 bytes
COST CENTRE MODULE %time %alloc
readPixelMap Main 33.0 11.0
readPixelMap.getByte Main 32.7 75.1
readPixelMap.getColor Main 27.0 13.3
Run Code Online (Sandbox Code Playgroud)
看来我的程序在函数中分配了大量的内存readPixelMap
.该函数如下所示:
readPixelMap width height = do
pixels <- replicateM height (replicateM width getColor)
return $ PixMap pixels
where getByte = liftM toInteger getWord8
getColor = do (red:green:blue:alpha:xs) <- replicateM 4 getByte
return (red, green, blue, alpha)
Run Code Online (Sandbox Code Playgroud)
和a PixMap
定义为
data PixMap = PixMap [[RGBAColor]] deriving (Show)
type RGBAColor = (Integer, Integer, Integer, Integer)
Run Code Online (Sandbox Code Playgroud)
readPixelMap
使用Get
monad来调用Data.Binary
:
main = do
binary <- BS.readFile "test.tga"
let (pixelMap, binary', nil) = runGetState (readPixelMap 2048 2048) binary 0
Run Code Online (Sandbox Code Playgroud)
我一直在努力工作的印象是2048 x 2048 .TGA图像应加载到几百兆(最多)的内存中.有没有明显的方法来改善我的垃圾收集时间/分配金额?
Car*_*arl 12
您的RGBColor
类型使用5个机器字,其中4个是每个机器字的指针Integer
.每个Integer
包含一个用于GC /标记的机器字,以及用于小型表示的一个附加字,或者包含指向GMP数据的字节数组的指针和肢体计数的大型表示.
此外,您正在使用列表列表来存储值.每个非空列表节点是用于GC /标记的单词,指向该值的单词指针,以及指向尾部的单词指针.
要使用更少的内存,请使用适当的数据类型.尽可能使用未打包的值.使用Word8
而不是Integer
8位值.使用数组而不是列表.你知道,像你一样关心记忆的基本知识.
请查看http://johantibell.com/files/slides.pdf了解一些基础知识.