Три подхода к увеличению производительности
Рефакторинг зачастую влияет на производительность. Чтобы сделать программный код или саму программу удобной для понимания, мы иногда вынуждены делать такие изменения, которые заставят работать программу медленнее, чем раньше.
Это важная проблема. И есть множество профессионалов, которые предпочитают писать более чистый и расширяемый код в ущерб его производительности, или надеясь на высокую производительность аппаратной части (железа). Рефакторинг, конечно, уменьшает производительности программы, но при этом делает программный код более податливым к дальнейшей оптимизации. Секрет быстрой программы заключается в том, что сначала ее код нужно сделать как можно более настраиваемым, а затем провести ее настройку в требуемой степени.
Вообще, существует три подхода к проектированию быстрых программ. Один из них, самый серьезный, заключается в том, что программа не должна превышать временные ресурсы, отведенные на ее работу. В этом случае, каждый компонент программы не должен превышать заданные программистом временные и дисковые ресурсы, несмотря на то, что может быть доступен механизм обмена этих времен. Этот механизм опирается на строго заданные времена, которые не должны превышаться. Это особенно важно для таких серьезных медицинских систем, как например сердечный ритмоводитель, в котором устаревшие данные недопустимы в принципе. Но такой подход будет излишним для других типов систем, например, корпоративных информационных систем.
Внимательный подход
Второй подход - постоянно уделять внимание коду. С таким подходом каждый программист все время делает что угодно, чтобы сохранить высокую производительность. Это общий подход, который интуитивно привлекателен, но плохо влияет на программный код. Изменения в коде, которые улучшают производительность, обычно делают процесс дальнейшей разработки (или поддержки кода) более сложным, т.е. такой подход замедляет процесс разработки. Улучшения производительности распространяются по всему коду, и каждое улучшение ограничивает перспективу дальнейших изменений поведения программы.
А вот интересная вещь, которую можно заметить: если проанализировать большинство программ, то окажется, что большую часть времени они тратят на небольшом участке кода. Это где-то 10% от всего кода в целом. И эти 10% отнимают 90% времени работы программы. Поэтому оптимизировать нужно именно узкие места в программе, а не остальные 90%, которые редко выполняются и тем самым незначительно влияют на производительность. Поэтому время, потраченное на увеличение производительности программы, можно считать потерянным, из-за недостатка ясности о том, что именно делает конкретный участок кода.
Улучшение производительности
Третий подход заключается в том, что когда Вы пишете программу, не нужно уделять внимание оптимизации (как во втором подходе). Эту оптимизацию Вы проведете позже уже после стадии разработки.
А сам процесс оптимизации будет заключаться в запуске программ-профилировщиков, которые покажут слабые места («горячие точки») в коде. Эти места в дальнейшем оптимизируются, используя второй подход. За счет того, что Вы концентрируетесь только на отдельных местах программы, это значительно экономит Ваше время. При этом подходе нужно делать изменения пошагово, запуская при этом профилировщик и смотреть, улучшилась ли производительность в модифицируемом месте программы. Если производительность не улучшилась, нужно убрать изменения, вернув код в прежнее состояние, т.к. он был отрефакторен. Таким образом, нужно повторить для каждого слабого места в Вашей программе до тех пор, пока не придете к удовлетворяющей Ваших пользователей производительности.
Хорошо отрефакторенный код помогает при этом подходе в двух случаях. Во-первых, он дает Вам время на улучшение производительности. Поскольку код хороший, он позволяет добавлять новую функциональность с минимальными затратами времени, а это позволяет больше сконцентрироваться на производительности (профилирование помогает находить нужные слабые места, а не концентрироваться на всем коде сразу). Во-вторых, если код отрефакторен, это означает, что функции, на которые будет указывать профилировщик и в которых могут быть слабые места, будут небольшими по объему. А их легче оптимизировать.
Вывод
Таким образом, из нашей сегодняшней статьи вытекает вывод: при правильном подходе рефакторинг не тормозит выполнение программы, а наоборот, позволяет легче ее оптимизировать. Программа работает медленно только в том время, когда она отрефакторена, но еще не оптимизирована. А оптимизировать отрефакторенную программу, как Вы поняли, гораздо легче, используя профилирование (анализ производительности отдельных частей кода).
Насколько я понял, речь в первом подходе идет о системах реального времени. Как раз в них больше всего гемора и наблюдается. Специальными программами код особо не проанализируешь, а рефакторинг ведется на таком низком уровне, что даже приоритеты процессам и механизмы их взаимодействия приходится расставлять вручную…