полный исходный код и профилирование отчет здесь: https://gist.github.com/anonymous/92334d00859c3db0ba8aЭффективный способ для создания больших объемов текста в Haskell
Я пытаюсь генерации большого текстового файла в виде файла изображения текста РРМ, и я я сталкиваюсь с некоторыми проблемами производительности. Я мог бы использовать другой формат изображения, но производительность генерации текста заинтересовала меня, поскольку у меня есть другие подобные ситуации, когда у меня нет гибкости выбора альтернативного формата.
Я начал с конкатенирования String
s вместе для создания текстового файла и быстро выяснил, что он занял почти 90% времени выполнения. Итак, я переключился на Data.Text
, но обнаружил, что производительность не была значительно улучшена. Я в конечном итоге производить тестовый файл, чтобы попытаться изолировать проблему, сравнивая две функции:
ppmS (Matrix mx) = unlines ["P3", show w', show w', "255", pixels]
where
w' = mxSize mx * scale
pixels = unlines $ map row [0..w'-1]
row j = intercalate " " $ map (pix j) [0..w'-1]
pix j i = color (mx ! (div i scale, div j scale))
ppmT (Matrix mx) = T.unlines ["P3", T.pack (show w'), T.pack (show w'), "255", pixels]
where
w' = mxSize mx * scale
pixels = T.unlines $ map row [0..w'-1]
row j = T.intercalate " " $ map (pix j) [0..w'-1]
pix j i = color (mx ! (div i scale, div j scale))
Идущие через профайлер, используя следующие команды:
ghc -O2 --make -prof -auto-all -caf-all -fforce-recomp test.hs
./test +RTS -p
я вижу следующее:
total time = 0.60 secs (597 ticks @ 1000 us, 1 processor)
total alloc = 1,162,898,488 bytes (excludes profiling overheads)
individual inherited
COST CENTRE MODULE no. entries %time %alloc %time %alloc
MAIN MAIN 96 0 0.0 0.0 100.0 100.0
main Main 193 0 24.1 14.7 24.1 14.7
CAF:main3 Main 188 0 0.0 0.0 39.9 37.0
main Main 225 0 0.0 0.0 39.9 37.0
main.ppmFromText Main 226 0 0.0 0.0 39.9 37.0
ppmT Main 227 0 8.5 9.3 39.9 37.0
ppmT.row Main 252 0 0.0 0.0 0.0 0.0
ppmT.pixels Main 250 1 8.7 9.3 31.3 27.7
ppmT.row Main 251 500 20.6 18.4 22.6 18.4
ppmT.pix Main 253 250000 1.8 0.0 2.0 0.0
color Main 254 250000 0.2 0.0 0.2 0.0
CAF:main6 Main 171 0 0.0 0.0 35.8 48.3
main Main 198 0 0.0 0.0 35.8 48.3
main.ppmFromString Main 199 0 0.0 0.0 35.8 48.3
ppmS Main 200 0 9.4 14.4 35.8 48.3
ppmS.pixels Main 216 1 8.5 14.5 26.5 33.9
ppmS.row Main 217 500 13.9 19.4 17.9 19.4
ppmS.pix Main 218 250000 3.5 0.0 4.0 0.0
color Main 219 250000 0.5 0.0 0.5 0.0
, который сообщает мне, что и версии Text
, и String
занимают значительное время и выделяют значительную память.
Что такое лучший способ генерировать этот текст, который более эффективен во времени & памяти?
Я не предлагаю, чтобы это проблема с производительностью, но вы можете избежать «T.pack» и «show» с помощью Text.Show (http://hackage.haskell.org/package/text-show) –