Параметры -O* задают удобные «пакеты» флагов оптимизации; описанные далее параметры -f* задают отдельные оптимизации, которые можно включать и отключать; параметры -m* задают зависящие от конкретной машины оптимизации, которые можно включать и отключать.
Большинство этих параметров являются логическими и имеют варианты для включения и отключения (начинающиеся с префикса no-). Например, если -fspecialise включает специализацию, то -fno-specialise отключает её. Если в командной строке указано несколько флагов для одного параметра, они обрабатываются слева направо. Например, -fno-specialise -fspecialise включит специализацию.
Важно отметить, что флаги -O* примерно эквивалентны комбинациям флагов -f*. Поэтому действие флагов -O* и -f* зависит от порядка, в котором они указаны в командной строке.
Рассмотрим, например, -fno-specialise -O1. Несмотря на то, что в командной строке указан -fno-specialise, специализация всё равно будет включена. Это происходит потому, что -O1 подразумевает -fspecialise, переопределяя предыдущий флаг. В отличие от него, -O1 -fno-specialise выполнит компиляцию без специализации, как и следовало ожидать.
5.3.1. -O*: удобные «пакеты» флагов оптимизации.
Существует множество параметров, влияющих на качество кода, генерируемого GHC. Большинство людей ставят перед собой лишь общую цель, например «Компилировать быстро» или «Сделать так, чтобы программа работала молниеносно». Следующих «пакетов» оптимизаций (или их отсутствия) должно быть достаточно.
Обратите внимание, что более высокие уровни оптимизации приводят к выполнению большего количества межмодульных оптимизаций, что может повлиять на объём программы, который необходимо перекомпилировать после внесения изменений. Это одна из причин обходиться без оптимизации при разработке кода.
Параметр типа ``-O*`` не указан: это означает: «Пожалуйста, компилируйте быстро; качество скомпилированного кода меня не слишком беспокоит». Например: ghc -c Foo.hs
-
-O0 -
Означает «отключить все оптимизации», возвращаясь к тем же настройкам, что и при отсутствии параметров
-O. Указание-O0может быть полезно, например, еслиmakeуже добавил-Oв командную строку.
-
-O -
-O1 -
Означает: «Генерировать качественный код, не тратя на это слишком много времени». Например:
ghc -c -O Main.lhs
-
-O2 -
Означает: «Применять все безопасные оптимизации, даже если это значительно увеличит время компиляции».
Избегаемые «опасные» оптимизации — это те, которые при неудачном стечении обстоятельств могут ухудшить время выполнения или потребление памяти. Обычно их включают или отключают по отдельности.
-
-O⟨n⟩ -
Любой параметр -On, где n > 2, эквивалентен -O2.
В повседневной работе мы не используем флаг -O*. Мы используем -O, чтобы получить достойную скорость; например, когда хотим что-то измерить. Когда мы хотим выжать максимум, то обычно используем -O2 (и делаем побольше перерывов на кофе).
Самый простой способ узнать, что -O (и другие подобные параметры) «на самом деле означают», — запустить компилятор с параметром -v, а затем отойти в сторону и изумиться.