Haskell, профилировщик
Проверяю, действительно ли enumerator+attoparsec работают в постоянной памяти.
Собираю с профилировочной информацией:
ghc.exe -odir obj -hidir obj --make "%1" -prof -auto-all -caf-all -fforce-recomp -rtsopts -fext-core
(если чо - в кабале перед установкой пакетов надо в конфиг поставить опцию library-profiling: True иначе будет ругаться при сборке)
затем запускаю прожку с профилировщиком
test.exe +RTS -p list2.txt >rr
list2.txt - файлик в 18 мег, 316 тыщ строк, список файлов на диске С :)
получаю файл test.prof, в котором есть такая забавная информация:
notNewLine, который так интенсивно долбится в память - совершенно тупой предикат:
Решил глянуть, что же ghc генерит для него:
Если я правильно понимаю написанное - оно на каждый вызов предиката конвертирует числа в Word8, выделяя под это память, а то и не один раз?
Хотя это какая-то хрень, оно должно такое вычислить один раз и дальше использовать готовое, по идее.
PS: Ага, включил -O2 - предикат стал работать как положено - 2% времени и 0% памяти. И общее потребление памяти вообще упало в 5 раз.
Собираю с профилировочной информацией:
ghc.exe -odir obj -hidir obj --make "%1" -prof -auto-all -caf-all -fforce-recomp -rtsopts -fext-core
(если чо - в кабале перед установкой пакетов надо в конфиг поставить опцию library-profiling: True иначе будет ругаться при сборке)
затем запускаю прожку с профилировщиком
test.exe +RTS -p list2.txt >rr
list2.txt - файлик в 18 мег, 316 тыщ строк, список файлов на диске С :)
получаю файл test.prof, в котором есть такая забавная информация:
COST CENTRE MODULE %time %alloc main Main 48.6 8.7 notNewLine Parsers 36.0 73.4 parseLine Parsers 10.6 15.5
notNewLine, который так интенсивно долбится в память - совершенно тупой предикат:
notNewLine :: Word8 -> Bool notNewLine 10 = False -- LF notNewLine 13 = False -- CR notNewLine _ = True
Решил глянуть, что же ghc генерит для него:
main:Parsers.notNewLine :: base:GHCziWord.Word8 -> ghczmprim:GHCziBool.Bool = \ (dsd2xh::base:GHCziWord.Word8) -> %note "SCC" %case ghczmprim:GHCziBool.Bool (base:GHCziClasses.zeze @ base:GHCziWord.Word8 base:GHCziWord.zdfEqWord8 dsd2xh (base:GHCziNum.fromInteger @ base:GHCziWord.Word8 base:GHCziWord.zdfNumWord8 (integerzmgmp:GHCziInteger.smallInteger (10::ghczmprim:GHCziPrim.Intzh)))) %of (wildB1::ghczmprim:GHCziBool.Bool) {ghczmprim:GHCziBool.False -> %case ghczmprim:GHCziBool.Bool (base:GHCziClasses.zeze @ base:GHCziWord.Word8 base:GHCziWord.zdfEqWord8 dsd2xh (base:GHCziNum.fromInteger @ base:GHCziWord.Word8 base:GHCziWord.zdfNumWord8 (integerzmgmp:GHCziInteger.smallInteger (13::ghczmprim:GHCziPrim.Intzh)))) %of (wild1X9::ghczmprim:GHCziBool.Bool) {ghczmprim:GHCziBool.False -> ghczmprim:GHCziBool.True; ghczmprim:GHCziBool.True -> ghczmprim:GHCziBool.False}; ghczmprim:GHCziBool.True -> ghczmprim:GHCziBool.False};
Если я правильно понимаю написанное - оно на каждый вызов предиката конвертирует числа в Word8, выделяя под это память, а то и не один раз?
Хотя это какая-то хрень, оно должно такое вычислить один раз и дальше использовать готовое, по идее.
PS: Ага, включил -O2 - предикат стал работать как положено - 2% времени и 0% памяти. И общее потребление памяти вообще упало в 5 раз.
no subject
(no subject)
(no subject)
(no subject)
no subject
(no subject)
no subject
no subject
no subject
Ещё дам замечательный пример —
sum [1..10005000]
Запускать без -O2.