профилирование памяти изменяет использование памяти ( к лучшему)

На самом деле это следующий вопрос этого вопроса. Мне удалось заставить работать профилирование, и проблема действительно в ленивой оценке.

Я использую структуру данных 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 ()

8
задан Community 23 May 2017 в 12:04
поделиться