На самом деле это следующий вопрос этого вопроса. Мне удалось заставить работать профилирование, и проблема действительно в ленивой оценке.
Я использую структуру данных Map Int (Map Int Text)
, где Text
взят из Data.Text . Проблема в том, что функция, строящая эту карту, создает огромный преобразователь. При работе с вводимым текстом размером около 3 МБ, программам требуется более 250 МБ памяти.
Теперь перейдем к реальной цели этого вопроса:
Чтобы получить количество символов в этой структуре данных, используйте следующую функцию:
type TextResource = M.Map Int (M.Map Int T.Text)
totalSize :: TextResouce -> Int
totalSize = M.fold ((+) . (M.fold ((+). T.length) 0)) 0
Не красиво, но выполняет свою работу. Я использую эту функцию в основной функции сразу после создания TextResource. Интересно то, что когда я профилирую программу с помощью параметра RTS -hr
или -hc
, использование памяти через некоторое время снижается до 70 или 50 МБ, что было бы совершенно нормально.
К сожалению, это работает только при использовании параметров профилирования и функции totalSize
- без них возвращается 250 МБ.
Я загрузил программу ( Ссылка
test.xml - это сгенерированный файл XML, который следует поместить в каталог исполняемых файлов.
Для сборки должно быть достаточно cabal configure --enable-executable-profiling
и затем cabal build
(если у вас установлены версии профилирования необходимых библиотек).
Вы можете увидеть изменение, запустив программу один раз с + RTS -hc
и один раз без него.
Было бы здорово, если бы кто-нибудь мог запустить программу, так как я действительно застрял Вот. Я уже пробовал вставить deepseq
в нескольких местах, но ничего не работает (ну, кроме использования параметров профилирования).
Правка:
Однако профилирование показывает, что используется только ~ 20 МБ кучи, поэтому в своем комментарии я виню GHC в том, что он не освободил столько памяти GC, сколько вам кажется.
Спасибо, что указала мне правильное направление. Как оказалось, вы можете указать GHC выполнить сборку мусора ( performGC ), которая отлично работает после глубокого просмотра карты. Несмотря на то, что я полагаю, что использование performGC не рекомендуется, кажется, что это правильный инструмент для работы здесь.
Edit2: Вот как я изменил основную функцию (+ глубокий запрос возврата buildTextFile):
main = do tf <- buildTextFile "test.xml"
performGC
putStrLn . show . text 1 1000 $ tf
getLine
putStrLn . show . text 100 1000 $ tf
return ()