52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 189

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 189

таблицу с показателями размера кучи, которые вычислитель замеряет через равные промежутки времени. Мы

можем изменять интервал с помощью флага iN, где N – время в секундах. Второй командой мы преобразуем

профиль в картинку. Флаг c, говорит о том, что мы хотим получить цветную картинку, а флаг e80mm, говорит

о том, что мы собираемся вставить картинку в текст LaTeX. После e указан размер в миллиметрах. Мы видим

характерный горб (рис. 10.10).

leak 6 +RTS -K30m -hc

3,008,476 bytes x seconds

Fri Jun 1 21:17 2012

bytes

14M

12M

(103)tick/sum2.iter/sum2/m...

10M

8M

(102)main.xs/main/Main.CAF

6M

4M

(101)sum2.iter/sum2/main/M...

2M

0M

0.0

0.1

0.1

0.2

0.2

0.2

seconds

Рис. 10.10: Профиль кучи для утечки памяти

В картинку не поместились имена функций мы можем увеличить строку флагом L. Теперь все имена

поместились (рис. 10.11).

$ ./leak 6 +RTS -K30m -hc -L45

(500000,500000)

$ hp2ps -e80mm -c leak.hp

С помощью флага hd посмотрим на объекты, которые застряли в куче (рис. 10.12):

$ ./leak 6 +RTS -K30m -hd -L45

(500000,500000)

$ hp2ps -e80mm -c leak.hp

Теперь куча разбита по типу объектов (замыканий) (рис. 10.12). BLACKHOLE это специальный объект, ко-

торый заменяет THUNK во время его вычисления. I# – это скрытый конструктор Int. sat_sUa и sat_sUd – это

имена застрявших отложенных вычислений. Если бы наша программа была очень большой на этом месте мы

бы запустили профилирование по функциям с флагом p и из файла leak. prof узнали бы в каких функциях

программа тратит больше всего ресурсов. После этого мы бы пошли смотреть исходный код подозрительных

функций и после внесённых изменений снова посмотрели бы на графики кучи.

Если подумать, что мы делаем? Мы создаём отложенное вычисление, которое обещает построить большой

список, вытягиваем из списка по одному элементу и, если элемент оказывается чётным, прибавляем к одному

элементу пары, а если не чётным, то к другому. Проблема в том, что внутри пары происходит накопление

отложенных вычислений, необходимо сразу вычислять значения перед запаковыванием их в пару. Изменим

код:

{-# Language BangPatterns #-}

module Main where