52700.fb2
0.1
0.1
0.2
0.2
0.2
seconds
Рис. 10.14: Профиль кучи без утечки памяти
module Main where
addEvens :: Int -> Int -> Int
addEvens a b
| even a && even b = a + b
q = zipWith addEvens [0, 2, 4, 6, 7, 8, 10] (repeat 0)
main = print q
Для того, чтобы воспользоваться флагом xc необходимо скомпилировать программу с возможностью про-
филирования:
$ ghc --make break.hs -rtsopts -prof
$ ./break +RTS -xc
*** Exception (reporting due to +RTS -xc): (THUNK_2_0), stack trace:
Main.CAF
break: break.hs:(4,1)-(5,30): Non-exhaustive patterns in function addEvens
Так мы узнали в каком месте кода проявился злосчастный вызов, это строки (4,1)-(5,30). Что соот-
ветствует определению функции addEvens. Не очень полезная информация. Мы и так бы это узнали. Нам
бы хотелось узнать тот путь, по которому шла программа к этому вызову. Проблема в том, что все вызовы
слились в один CAF для модуля. Так разделим их:
$ ghc --make break.hs -rtsopts -prof -caf-all -auto-all
$ ./break +RTS -xc
*** Exception (reporting due to +RTS -xc): (THUNK_2_0), stack trace:
Main.addEvens,
called from Main.q,
called from Main.CAF:q
--> evaluated by: Main.main,
called from :Main.CAF:main
break: break.hs:(4,1)-(5,30): Non-exhaustive patterns in function addEvens
Теперь мы видим путь к этому вызову, мы пришли в него из знчения q, которое было вызвано из main.
10.7 Оптимизация программ
В этом разделе мы поговорим о том этапе компиляции, на котором происходят преобразования Core ->
Core. Мы называли этот этап упрощением программы.
172 | Глава 10: Реализация Haskell в GHC
Флаги оптимизации
Мы можем задавать степень оптимизации программы специальными флагами. Самые простые флаги на-
чинаются с большой буквы O. Естесственно, чем больше мы оптимизируем, тем дольше компилируется код.
Поэтому не стоит увлекаться оптимизацией на начальном этапе проектирования. Посмотрим какие возмож-
ности у нас есть:
• без -O – минимум оптимизаций, код компилируется как можно быстрее.
• -O0 – выключить оптимизацию полностью
• -O – умеренная оптимизация.
• O2 – активная оптимизация, код компилируется дольше, но пока O2 не сильно выигрывает у O по про-
дуктивности.
Для оптимизации мы компилируем программу с заданным флагом, например попробуйте скомпилиро-