我试图为下面这个简单的Haskell代码生成堆内存分析报告,该代码是用于复制文件的:
import System.Environment
import System.IO
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as LB
naiveCopy :: String -> String -> IO ()
naiveCopy from to = do
putStrLn $ "From: " ++ from
putStrLn $ "To: " ++ to
s <- B.readFile from
B.writeFile to s
main = do
args <- getArgs
mapM (\ x-> putStrLn x) args
naiveCopy (head args) ((head.tail) args)
使用ghc 8.0.1编译代码的命令:
ghc -o t -rtsopts -prof -fprof-auto t.hs
收集性能数据的命令:
./t +RTS -p -h -RTS in/data out/data && hp2ps -e8in -c t.hp
这里,in/data
是一个相当大的文件(约500MB),拷贝该文件程序将需要大约2秒钟。
问题在于,如果我使用严格模式下的 Data.ByteString
,就无法获得堆剖析数据,只会生成一个小小的 t.hp 文件而没有样本数据,如下所示:
JOB "t in/data out/data +RTS -p -h"
DATE "Thu Aug 4 20:19 2016"
SAMPLE_UNIT "seconds"
VALUE_UNIT "bytes"
BEGIN_SAMPLE 0.000000
END_SAMPLE 0.000000
BEGIN_SAMPLE 0.943188
END_SAMPLE 0.943188
然而,如果我切换到lazy版本Data.ByteString.Lazy
,则可以获得堆分析数据,配置表如下所示:
更新:感谢@ryachza,我添加了一个-i0
参数来设置采样间隔并再次尝试,这次我得到了strict ByteString
的采样数据,并且看起来很合理(我正在复制一个500M的文件,下面的配置表中内存分配峰值约为500M)。
./t +RTS -p -h -RTS in/data out/data && hp2ps -e8in -c t.hp
JOB "t in/data out/data +RTS -p -h" DATE "Thu Aug 4 20:19 2016" SAMPLE_UNIT "seconds" VALUE_UNIT "bytes" BEGIN_SAMPLE 0.000000 END_SAMPLE 0.000000 BEGIN_SAMPLE 0.943188 END_SAMPLE 0.943188
- 6bb79df9