Нет данных профилирования кучи для модуля Data.ByteString
Я пытался сгенерировать профиль памяти кучи для следующего наивного кода на 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
довольно большой файл (около 500 МБ), на копирование которого потребуется около 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
и соответствующий профиль профиля, как это:
Однако я мог бы получить данные профилирования кучи, если я переключился на ленивую версию Data.ByteString.Lazy
, профиль профиля, как это:
Обновление: спасибо ryachza, я добавил -i0
параметр, чтобы установить интервал выборки и попробовал еще раз, на этот раз я получил образцы данных для строгого ByteString
и это выглядело разумно (я копировал файл 500M, а пик распределения памяти в следующей таблице профилирования составляет около 500M)
./t +RTS -p -h -RTS in/data out/data && hp2ps -e8in -c t.hp
1 ответ
Похоже, что среда выполнения не "получает возможность измерить" кучу. Если вы добавите -s
на ваш RTS
параметры, он должен печатать некоторое время и информацию о распределении. Когда я запускаю это, я вижу выделенные байты и общее использование памяти очень велико (размер файла), но максимальная резидентность (и количество выборок) очень низка, и хотя истекшее время велико, фактическая "работа" "время практически 0.
Добавление опции RTS -i0
позволил мне воспроизводимо визуализировать распределение байтовых строк как PINNED
(это классификация, потому что байтовые массивы, которые использует внутренняя строка, расположены в области, в которой GC не может перемещать объекты). Вы могли бы поэкспериментировать с разными -h
варианты, которые связывают ассигнования с различными центрами затрат (например, -hy
должен показать ARR_WORDS
) но это, вероятно, не будет иметь большого значения в этом случае, поскольку байтовые строки на самом деле являются просто "большими кусками необработанной памяти".
Ссылки, которые я использовал, чтобы найти параметры RTS, были (очевидно, я не особо относился к версии GHC - я не могу представить, чтобы эти флаги часто менялись)