Оптимизация кода — лишь один из способов повышения производительности программы. Часто можно найти другие способы, обеспечивающие большее повышение производительности за меньшее время и с меньшим вредом для кода (c. 573).
Производительность программы лишь косвенно связана с быстродействием кода. Обычно пользователей больше интересуют потребительские характеристики, а не быстродействие. Если производительность не так ужасна, что мешает пользователю решать его задачу, возможно, её и не стоит улучшать.
Улучшение производительности не ограничивается кодом и может быть реализовано на разных уровнях:
- Требования к программе (из-за необоснованно завышенных требований к быстродействию можно потратить деньги впустую, поэтому прежде чем решать проблему с производительностью, убедитесь, что проблема действительно есть)
- Проект программы (правильно спроектированная инфраструктура, удачный выбор архитектурных паттернов и тому подобные факторы могут обеспечить более существенный прирост производительности, чем оптимизация кода)
- Проект классов и методов (на этом этапе важно выбрать подходящие для эффективного решения задачи структуры данных и алгоритмы)
- Взаимодействие программы с ОС
- Компиляции кода
- Обновление оборудования
- Оптимизация кода (изменение корректного кода с целью улучшить его быстродействие)
Оптимизация кода привлекательна по ряду причин. Прежде всего она бросает вызов законам природы. Нет ничего радостнее, чем ускорить выполнение метода в 10 раз путем изменения всего лишь нескольких его строк (c. 576).
Дональд Кнут писал, что менее 4% кода обычно соответствуют более чем 50% времени выполнения программы. Этот принцип справедлив для большинства программ, поэтому:
- Нужно сосредоточиться на исправлении того кода, который исполняется чаще всего
- Проблемные фрагменты кода можно переписать на быстром компилируемом языке, таком как C
- Если в программе меньше строк, это ещё не означает, что она быстрее работает
- Если вам кажется, что лучше всего оптимизировать код по мере его написания, вы, скорее всего, потратите множество лишних часов впустую, например, оптимизируя редко используемые методы – гораздо лучше оптимизировать производительность кода, когда вы понимаете, где находятся слабые места
- Быстродействие программы не может быть важнее её корректности
Современные компиляторы могут оптимизировать код куда эффективнее, чем вам кажется. В случае, который я описал выше, мой компилятор выполнил оптимизацию вложенного цикла так эффективно, что я едва ли получил бы лучшие результаты, переписав код (c. 582).
Без профилирования программы вы никогда не сможете с уверенностью сказать, какие фрагменты медленны и огромны, но некоторые операции давно славятся ленью и ожирением, так что вы можете начать исследование именно с них (c. 583).
- Операции ввода/вывода
- Замещение станиц в памяти
- Системные вызовы
- Интерпретируемые языки
Понять слабые места написанного кода или оценить результаты проведённой оптимизации можно только с помощью профилирования.
...единственным результатом оптимизации, в котором можно быть полностью уверенным без измерения производительности, является затруднение чтения кода (c. 589).
-
Напишите хороший и понятный код, поддающийся легкому изменению.
-
Если производительность вас не устраивает:
a. сохраните работоспособную версию кода, чтобы позднее вы могли вернуться к «последнему нормальному состоянию»
b. оцените производительность системы с целью нахождения горячих точек
c. узнайте, обусловлено ли плохое быстродействие неадекватным проектом, не верными типами данных или неудачными алгоритмами и определите, уместна ли оптимизация кода; если оптимизация кода неуместна, вернитесь к п. 1
d. оптимизируйте узкое место, определенное на этапе (c)
e. оцените каждое улучшение по одному за раз
f. если оптимизация не привела к улучшению кода, вернитесь к коду, сохраненному на этапе (a) (как правило, более чем в половине случаев попытки оптимизации будут приводить лишь к незначительному повышению производительности или к ее снижению)
-
Повторите процесс, начиная с п. 2.