- PVSM.RU - https://www.pvsm.ru -

Своевременная оптимизация

Всем известно, что преждевременная оптимизация — это плохо и надо себя одёргивать когда, возникает желание пооптимизировать не вовремя. Однако на практике чаще бывает ситуация когда естественное (и, возможно, интуитивно правильное) желание пооптимизировать подавляется по принципу «если вообще не оптимизировать — это не будет преждевременно». Либо так:

Своевременная оптимизация - 1

На мой взгляд, подобные ситуация возникают потому, что границы понятия «преждевременности» весьма нечёткие и интуитивные, как будто это что-то эмпирическое и неуловимое вроде сочности хруста французской булки.

Хотя в принципе довольно странно оперировать какими-то эмпирическими понятиями по отношению к архитектуре программ, алгоритмам и их оптимизации — поскольку это вполне измеримые вещи. А значит — можно достаточно просто измерить своевременность оптимизации. Об этом и поговорим.

Что такое оптимизация?

Оптимизация простыми словами — это приведение программы от состояния «не устраивает» до состояния «устраивает» по параметрам производительности (время выполнения, потребление ресурсов, пропускная способность). Т.е. мы знаем, какие показатели нас устраивают, и когда мы видим, что программа до них не дотягивает — пора её оптимизировать.

Что такое преждевременная оптимизация?

В тех случаях, когда мы думаем, что попадаем в состояние «не устраивает», а на самом деле всё «устраивает» — мы оптимизируем преждевременно.

Что такое своевременная оптимизация?

Мы знаем, что программа нас уже/вот-вот/будет «не устраивать» — и принимаем меры по исправлению ситуации.

В идеальном мире мы создаём программу, удовлетворяющую требованиям, выпускаем её на волю — и там нас всё сразу «устраивает». Как случается в реальном мире чаще всего, мы все прекрасно знаем.

К счастью, чтобы понять, своевременно или преждевременно мы оптимизируем, нужно совершить одни и те же действия и для этого обычно достаточно листка бумаги.

Измеримая своевременность

В общем и целом, само по себе измерение своевременности/преждевременности требует довольно простых действий:

  1. Взять требования по производительности
  2. Посчитать, укладывается ли программа в эти требования
  3. Если укладывается — жить счастливо; в противном случае — оптимизировать программу

Поскольку самым распространённым требованием является время отклика, пропускная способность сводится к нему же, а потребление ресурсов отдельная и большая тема сконцентрируемся на первом.

Итак, у нас есть требуемое время выполнения программы — ТВ и требуемое кол-во обрабатываемых данных за проход — ТД.

Мы ещё только проектируем или разрабатываем программу, и нас не покидает ощущение, что что-то идёт не оптимально и возникает боязнь преждевременной оптимизации. Для измерения нашего ощущения и предотвращения развития фобии нужно выполнить следующие действия:

  1. Определить временную сложность спроектированного/разработанного алгоритма O(n), учитывая константы. 3*n так 3*n, n*logn + n и т.п. Чем точнее — тем лучше.
  2. Получить кол-во выполняемых операций за проход — КО путём подстановки ТД в функцию, описывающую временную сложность.
  3. Посчитать среднее допустимое время обработки одного элемента — СВЭ входного массива (подразумеваем верхнеуровневую сущность, один документ, одного пользователя) на основе TB. Т.е.
    СВЭ = TB / KO
  4. Далее мы убеждаемся что фактическое время обработки одного элемента <= среднего допустимого времени обработки одного элемента, при необходимости повторяя шаги 1 и 2 для программ/алгоритмов находящихся выше по стэку.

Разберём простой пример

Допустим, что нам нужно написать программу, которая должна обработать 100 записей и уложиться в 2 секунды. В ходе разработки мы придумали некий алгоритм, временная сложность которого O(n^2).

В таком случае у нас есть 2/100^2=2*10^-4 секунд (0,2 миллисекунд или 200 микросекунд) в среднем для обработки каждой записи. Этого хватит для выполнения простых действий (арифметика и обращения к памяти занимают десятки или сотни наносекунд, если, например, судить по этой инфографике [1]), но какие бы то ни было сетевые взаимодействия уже становятся недоступны.

Т.е. если мы пишем сортировку массива чисел под такие требования — нас «устраивает», а если нам нужно отправить 100 запросов SOAP — нас «не устраивает» и пора что-то придумывать.

Заключение

В общем-то это всё, данный подход легко масштабируем и позволяет легко оценить верхнюю границу своевременности, избавляет от чувства неопределённости и повышает осмысленность производимых программ. А самое главное — делает ваших пользователей и менеджеров счастливыми, поскольку в продакшене меньше горит.

Естественно, этого подхода недостаточно для вывода в промышленную эксплуатацию — поэтому проконсультируйтесь со специалистом прежде, чем отказываться от нагрузочных испытаний.

Спасибо за внимание!

Автор: bashnesnos

Источник [2]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/optimizatsiya-koda/249381

Ссылки в тексте:

[1] по этой инфографике: http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/

[2] Источник: https://habrahabr.ru/post/323884/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox