Как стать программистом и избежать детских ошибок Преждевременная оптимизация
Приветствую всех, кто оставался на связи!
Я возобновляю эти блог и рассылку в прежнем формате.
Давайте сегодня затронем тему, которая должна быть в любом учебнике или курсе. Тему, которая выглядит технической, хотя имеет психические корни. Кажется безобидной, но влечёт огромные расходы времени и сил.
Итак, вопрос в фокусе: нужно ли оптимизировать программы?
Что такое оптимизация
В большинстве случаев под оптимизацией подразумевают ускорение программ. Это повелось ещё с тех времён, когда процессоры были слабыми и безжизненными. Многим быстродействие программ, а точнее скорость исполнения алгоритма, и сегодня кажется ключевым приоритетом.
Тем не менее, тут кроется ловушка. Во-первых, процессор далеко не единственный фактор быстродействия, и в большинстве случаев совсем не главный. Во-вторых, ценным ресурсом бывает не только быстродействие программы.
С этой позиции, давайте будем считать оптимизацией те усилия, ходы, трюки и прочее, которые направлены на экономию ценного ресурса. Напрасной же оптимизацией будет экономия ресурса, который и без того имелся в избытке.
Что можно выгадать
Для полноты картины вспомним, какие ресурсы затрагивает программа (особенно Веб-приложение):
Процессорное время. Помним о том, что на Веб-сервере работает много программ, а главное много экземпляров одной программы. Таким образом, даже если на компьютере разработчика всё летает (в единственном экземпляре), высокопосещаемого сервера на всех может не хватать.
Оперативная память. Некоторые программы, в частности достопочтимый Apache, занимают по несколько мегабайт на экземпляр. Таким образом, если ваши программы отрабатывают долго, например, отдавая большие файлы всем желающим, то объём ОЗУ это тот ресурс, в который Вы упрётесь первым делом.
Объём диска. В целом понятно.
Скорость чтения с диска. Если программа оперирует большими объёмами данных, фактор начинает сказываться.
Скорость обращения к диску. Как правило поиск чего-то на диске, или многократные к нему обращения занимают много больше времени, чем чтение с него того же объёма данных в один блок.
Скорость срабатывания других программ. Поскольку мы пользуемся инструментами других разработчиков, приходится учитывать и их ограничения. Например, плохо написанный SQL-запрос может вогнать SQL-сервер в долгий цикл его обработки. Кстати, не стоит бояться таких запросов. Их надо просто вовремя отлавливать.
Время разработки. Вот важный фактор, неочевидный сначала, но становящийся заметнее с опытом.
Стоимость разработки. Этот пункт совершенно не тождественен предыдущему, и у большинства программистов с ним затруднения. Оптимизация проекта по стоимости задача управленцев.
Где преждевременность?
Что будет, если мы оптимизируем программу, скажем, по оперативной памяти, а она так и не дойдёт до стадии внедрения из-за пропавшего интереса (долго была в работе)? Или оптимизируем по использованию процессора, а узким местом оказывается скорость обращения к диску, причём на процессоре 90% ресурса постоянно свободные, а отклик программы достигает 5 секунд?
Это, кстати, реальные ситуации. Так вот, время и силы на техническую оптимизацию потрачены, читаемость кода местами принесена в жертву (а это ещё время и силы в кредит, проценты по которому придётся гасить в дальнейшем), и выигрыша ноль.
Ладно, бог бы с ними, с силами. Опыт получен. Однако ж и опыт оказывается некачественным! Сейчас разберёмся, почему.
Откуда взялось желание заняться оптимизацией? Обычно всё просто: ресурс показался ценным, захотелось сэкономить. Но эта идея не проверялась. Никак. А надо было.
Таким образом, вероятность того, что она окажется характерной для нашей отрасли невелика.
Увы, так и происходит, поскольку действительно важное неочевидно (кстати, именно поэтому опыт имеет ценность). Но пройдя по неверному пути, мы получили и опыт преодоления трудностей именно этого пути. То есть те навыки, которые станут нам обузой, когда мы, наконец, определим, чем действительно важно заниматься.
Что делать
«Быть Буддой означает знать через наблюдение, а не через веру Писаниям или мне», сказал некий авторитетный в своих кругах монах Аджан Сумедхо.
Именно так следует поступить и с оптимизацией:
Знать перечисленные выше направления.
Точно знать, являются ли два последних приоритетными для Вашего проекта.
Примерно знать будущую нагрузку проекта, и вероятность её достижения.
Попробовать раздобыть информацию, какие проблемы были у разработчиков аналогичных проектов. Не стоит полагаться на эту информацию, но плясать от чьих-то данных лучше, чем от выдуманных.
Делать, как быстрее делается, но предусмотреть способы замера скоростей и поиска узких мест.
Устранять узкие места, по мере их выявления. Ещё раз ключевые слова: а) узкие места, б) по мере выявления.
Я применяю такую стратегию: разрабатывать, как быстрее. А если проект «выстрелил», то узкие места можно переписать. Переписывается код под идентичный функционал на порядки дешевле, чем тот же функционал разрабатывается. А средства профилирования заложены у меня в используемый инструментарий.
Вся оптимизация, проведённая до того, как Вы увидели узкие места, является преждевременной и в итоге, как правило, напрасной.
Вы можете задать мне любой вопрос. Все полученные мною вопросы могут быть опубликованы в рассылке. Если Вы желаете скрыть свои личные данные из вопроса укажите это в тексте письма, поскольку в дальнейшем, письма будут публиковаться с полными подписями (без емейлов, разумеется).