Подтвердить что ты не робот

Должен ли я всегда думать о производительности?

Я пришел из мира DBA, и производительность всегда была одержимостью. Я обращаюсь к развитию, и я всегда думаю о производительности, постоянно, все время.

Чтение на SO иногда кажется, что производительность не имеет значения. Например, для евангелистов в спящем режиме (или любых других ОРМ).

Как разработчик, когда мне приходится думать о производительности, а когда нет?

4b9b3361

Ответ 1

Вообще говоря, одержимость производительности или оптимизации - это путь к большому злу в разработке программного обеспечения. Обычно только около 5% (или меньше!) Вашего кода влияет на производительность всей системы. Ваши основные цели, во-первых, как разработчик программного обеспечения в большинстве проектов, - это исправление и надежная функциональность, а также, конечно же, ремонтопригодность системы. Затем, после правильной работы и правильной работы, вы оцениваете производительность, узнаете, где узкие места, и оптимизируйте их соответственно для достижения ваших общих целей.

One Caveat. Выполнение оценок типа O (n) подходов, которые вы принимаете к вещам, - разумные вещи, которые нужно заранее рассмотреть в рамках первоначальной разработки системы и выбора алгоритма и т.д., чтобы просто чувствовать себя уверенно спектакль будет "в шаровом парке". Но помимо этого большинство попыток оптимизировать вещи до фактического измерения того, где узкие места будут приводить к оптимизации вещей, которые не имеют значения, и обычно делают вещи менее удобными, труднее понять и т.д.

Ответ 2

цитата Knuth ( "Мы должны забыть о небольшой эффективности, скажем, около 97% времени: преждевременная оптимизация - это корень всех зло" ), вероятно, применяется.

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

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

Ответ 3

Когда это происходит?

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

Как и в случае масштаба, так же как и потребность в оптимизированных путях, как в коде, так и в доступе к данным и коммуникации. Если вы работаете с ограниченным оборудованием (встраиваемыми системами), вы очень заботитесь о производительности. Но есть много, много приложений, которые никогда не увидят достаточного количества пользователей, чтобы заставить системные ресурсы даже заметить, что вы там.

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

Ответ 4

Я думаю, что здесь есть две противоречивые пословицы.

1: Преждевременная оптимизация - это корень всего зла.

2: Посмотрите, прежде чем прыгать.

В моем личном опыте, это было так, когда при первом написании кода вероятность найти магию 3% кода, использующего 90% ресурсов, очень легко найти. Именно здесь важна первая пословица и, кажется, дает отличные результаты. Однако, поскольку база кодов созревает, похоже, что вместо 3%, используя 90% ресурсов, вы вдруг получаете 50%, используя 90% ресурсов. Если вы представляете себе аналогию с водопроводом, а не с несколькими большими утечками, у вас теперь есть проблема с несколькими небольшими утечками по всему месту. Это дает общее приложение медленной производительности, даже если его трудно привязать к любой отдельной функции.

Вот где пословица 2 кажется актуальной. Не полагайтесь на первую пословицу, чтобы не выполнять планирование производительности, иметь общий план, даже если он развивается. Попробуйте разработать некоторые приемлемые показатели производительности и время вашей программы. Рассмотрим более поздние последствия выбора дизайна. Например, можно планировать использование магазина кортежей, а не базы данных заранее, если все, что необходимо, является магазином кортежей. Начиная с базы данных SQL, а затем перейдя в магазин кортежей, это довольно сложно.

Прежде всего, постарайтесь оптимизировать, где легко и делать заметки о случаях, когда возможна оптимизация. Если вы этого не сделаете, с течением времени программы, как правило, страдают от смерти тысяч сокращений, так как эффект функций на 5-20% медленнее, чем их нужно складывать и действительно умножать.

Ответ 5

Ссылаясь на преждевременную оптимизацию Knuth. evil '- плохой аргумент для написания неаккуратного и медленного кода (правильно или иначе).

  • Вам нужны метрики для оптимизации.
  • Вам нужно подумать о коде, когда вы его кодируете.
  • Вы оптимизируете только подмножество кода.

Если вы пишете простую форму для обновления некоторых деталей, это, вероятно, не стоит оптимизировать.

Если вы пишете замену поисковой системы Google, и вы ожидаете, что у вас будет большой трафик, вы поймете способ сделать этот поиск как можно быстрее.

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


Учитывая, что мы удовлетворяем 1, 2 и 3 выше:

Там мало смысла ждать, пока приложение будет на 90% заполнено, прежде чем выполнять какие-либо проверки производительности и оптимизации. Производительность часто является неписаным нефункциональным требованием. Вам нужно определить и записать, какие из этих неписаных требований и передать им.

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

Затем, если у вас есть хорошо написанные модульные тесты, вы должны иметь тесты производительности как часть этих тестов.

Мои 2 шиллинга как минимум.

Ответ 6

У меня была фаза, где я был абсолютно параноик о производительности. Я потратил столько времени, пытаясь повысить производительность, что мой код никогда не продвигался. Не входите в эту привычку: -)

Код, ТОГДА оптимизируйте, а не оба одновременно.

Ответ 7

Производительность - это не то, что может вставляться в конце проекта.

Ответ 8

Не думайте о производительности, пока не получите правильную работу. Если он работает правильно и не имеет каких-либо проблем с пользователем, не оптимизируйте его.

Если он работает правильно и имеет значительные и заметные задержки, не оптимизируйте. Профиль. Большая часть времени приложения будет потрачена в одном "горячем" цикле, а какой цикл он малоинтуитивен. Вам нужны реальные измерения и наука, чтобы рассказать вам, что происходит. После того, как у вас есть данные профиля, ваша задача оптимизации должна перейти от большого к маленькому:

  • Оптимизация архитектуры. Является ли общая структура приложения источником неэффективности?

  • Оптимизация алгоритмов: используете ли вы правильные структуры данных? Вы обращаетесь к ним правильно? Ваше приложение тратит большую часть времени на запись или большую часть времени на чтение? Оптимизируйте ответ на этот вопрос.

  • Последняя инстанция. Microoptimization. Упорядочение горячих циклов или разворот некоторых циклов. Дафф-устройство. Не оптимизируйте этот уровень до тех пор, пока вы не решите, что не сможете добиться дальнейших улучшений на двух других уровнях, и вы все еще не достигли своих целей. Этот уровень оптимизации имеет высокую вероятность сломать дерьмо и сделать ваше приложение более трудным для роста, более хрупким, поэтому не делайте этого, если вам действительно не нужно.

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

Ответ 9

Вы должны оптимизировать производительность после того, как вы создали свое приложение, и только если у вас есть доказательства, где ваши узкие места. (Например, профилирование) Возможно, вы обнаружите, что нет необходимости оптимизировать, особенно потому, что компилятор обычно намного лучше, чем вы.

Ответ 10

Когда мне нужно думать о производительности, а когда нет?

Вы можете думать о производительности, всякий раз, когда вы избавляете любые циклы от размышлений о правильности.: -)

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

Ответ 11

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

Ответ 12

Я работаю над созданием поисковой системы. Оптимизация - это то, что делает разницу между пользователем, продолжающим искать или покидать веб-сайт. Я думаю, что это верно для многих приложений, и, к сожалению, многие из них не заботятся об этом. Иногда гораздо дешевле бросать больше аппаратных средств в проблему. К сожалению, последнее проще. Подводя итог, я бы сказал, что вам нужно оптимизировать всякий раз, когда вам либо приходится обрабатывать много данных и/или обрабатывать их очень быстро.

Ответ 13

Я нахожу, что мой типичный образец для работы через единицу разработки:

  • Сопоставьте наименьшую версию, которая работает в основном случае использования от начала до конца. На этом шаге я в основном фокусируюсь на простой простоте и хорошей реализации любых шаблонов.

  • Шаг 2 - это этап рефакторинга 1, главным образом, с целью упрощения. Поскольку я занимаюсь ООП, единственное, на что я могу рассчитывать, это то, что на этом этапе всегда много очевидных упрощений и фактического сокращения кода. Это также точка, в которой очевидные абстракции выпадают (что является еще одним упрощением). ВАЖНОЕ ПРИМЕЧАНИЕ. У этого есть сильный вторичный эффект эффективности адресации, особенно если вы сделали это несколько раз, и знаете, где действуют антипаттеры.

  • Часто, когда # 2 сделано, все удовлетворительно выполнено, но тесты подтвердят это или нет; а также указать (как правило, очень немногие) места, где необходимо оптимизировать оптимизацию.

Все чаще я вижу, что в любое время, когда я размышляю об эффективном дизайне в фазах 1 и 2, я теряю простоту, которая в этот момент является первичной.

Ответ 14

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

Другой пример... в моей предыдущей работе я работал в Data Processing, написав скрипты вокруг исполняемых программ. Если бы я начал программу в 17 часов вечера, и на следующее утро она закончилась к 8 часам утра, это было достаточно быстро. Конечно, в случае чрезвычайной ситуации для него было намного лучше, чем на один час вместо десяти, и более быстрый код облегчил мою работу, но, пока он работал правильно, 30 минут соответствовали 16 часам.

Это полностью зависит от вашего проекта... и его следует учитывать в ваших проектных требованиях.

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

Ответ 15

Обычно это сводится к требованиям. В некоторых случаях у вас очень строгие не функциональные требования для времени отклика и т.д. В этих случаях вы должны приложить дополнительные усилия для настройки кода, процедур и т.д.

Но как правило (IMHO), вы должны создать свой код на основе передового опыта по надежности и целенаправленности, а затем провести определенный раунд тестов по производительности. Таким образом, вы будете знать, что вы будете настраивать только биты кода, которые фактически влияют на производительность.

Ответ 16

Ответ 1:

Многие люди справедливо говорят "Не думайте о производительности, оптимизируйте позже", но помните, что они имеют модульные тесты. Они могут переписывать большие части своей кодовой базы, не опасаясь вводить ошибки. Если вы переписываете без каких-либо модульных тестов, вам нужно снова вручную протестировать все, и на этот раз это сложнее, потому что алгоритмы сложнее.

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

Ответ 2:

Иногда простое рабочее решение, с которым вы впервые сталкиваетесь, запускается в O(n^n) времени. Если вы знаете, что у вас будут большие наборы данных, тогда идите и оптимизируйте их сейчас.

Ответ 3:

Некоторое время назад я устал от пятен на PHP и пытался исправить некоторые из них. Я написал фреймворк, который включал базовый класс, из которого все нужно было наследовать. Он использовал метод и перегрузку свойств, отражение и практически любую другую расширенную функцию, чтобы заставить ее работать. Затем я пошел вперед и использовал его в массивном проекте, используя собственные функции фрейма вместо основных функций языка, таких как isset() и static. Код проекта был немного более аккуратным, но магия замедлила каждый вызов метода и доступ к свойствам примерно на 50x.

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

Ответ 17

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

Смысл - если он не собирается получать тонну использования, волнуйтесь соответственно. Не будьте невероятно ленивы или неэффективны, и не переусердствуйте в получении алгоритмической нирваны каждый раз. Часто лучше всего простейший код и сделать его быстрее/оптимизированным по мере необходимости. Тем временем простой код может быть обработан любым разработчиком, и это заслуживает рассмотрения.

Если вы видите, что это значение возрастает, теперь вы знаете, чтобы думать об этом еще больше, так как вам придется укусить вас сзади.

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

Хорошим примером для меня было то, что я начал играть с базами данных много лет назад. Я не знал, какие дополнительные индексы или большие повышения производительности они дают, когда запросы невообразимо замедляются.

Мы не можем предсказать каждую проблему. Я стараюсь делать хороший дизайн, и пусть проблемы борются за мое внимание.

Надеюсь, что-то было полезно.

Ответ 18

Лучше всего написать код, а затем определить критические области, которые лучше всего выиграют от оптимизации.

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

Ответ 19

Нет, если вы собираетесь что-то подумать, подумайте о том, чтобы доставить ценность вашему работодателю/клиенту и клиентам. Подумайте о том, что для них важно.

Тем не менее, производительность важна, но может привести к гибели.

Dawn of War 2 был выпущен в феврале с ошибкой игры, которая уничтожает мультиплеер. Проблема? Колпак населения. Когда отряд повторно применяется, последний блок занимает удвоенную колпачку из-за ошибки кодирования. Это означает, что вы можете находиться в ситуации, когда у вас очень маленькая армия, и когда вы пытаетесь создать новое подразделение, игра говорит вам, что у вас слишком много единиц на поле. Самое разочаровывающее.

Почему это должно быть проблемой? Как это может быть проблемой, которая возникает только при повторном исполнении? Если это была проблема с покупкой устройства, то, несомненно, это было бы обнаружено при тестировании!

Хорошо, я предполагаю, что это связано с преждевременной оптимизацией. Разработчик не захотел отображать все единицы, когда вы нажимаете кнопку "купить блок", и вместо этого делает pop-cap, как банк, поэтому, когда создается единица, она берет колпачок из банка и когда он умирает, обратно в банк. Уверенный, что более результативная, но одна маленькая ошибка бросает весь банк в ногу.

Итак, что еще хуже, маленький перфомант, когда вы нажимаете кнопку "купить блок" или много пылающего на форуме Dow2, сердитые клиенты и MS перетаскивают каблуки с подтверждением исправления, означающего, что он еще не исправлен?

Во многих случаях его лучше маркировать

// todo: performance could be better
// try doing xyz if we need to improve it

потому что исполняемая версия занимает больше времени и добавляет стоимость обслуживания к коду.

Эффективность, о которой вы должны беспокоиться, - это решение для вашего клиента, которое удовлетворительно и отвечает их потребностям. Скорость перехода к дате выпуска обычно важнее.

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

Ответ 20

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

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

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

Оптимизация - это глагол, который принимает объект. Пока у вас нет этого объекта, вы не можете его оптимизировать. Вы можете оптимизировать код после его написания (хотя это может быть только один метод). Вы можете оптимизировать модель класса или функциональную спецификацию после их написания.

Работа над производительностью - это вопрос, нацеленный на оптимальное, будь то априорное или апостериорное. Какая-то работа по производительности является только подходящей апостериорной, и это то, что следует считать оптимизацией, и преждевременно делать априори. Некоторая работа по производительности, как и более, подходит априори.

Главное, чтобы попытаться получить априори, является ли ваш базовый подход разумным. Одним из примеров, которые часто приводятся здесь, является временная сложность алгоритмов, но я должен не согласиться. Не всегда лучше делать что-то в O (1) или O (n log n), чем в O (n). Время O (n) совпадает с временем O (1), когда n равно 1, и быстрее, когда n равно 0, а набор данных с 0 или 1 элементом может быть распространен во многих случаях. Более того, нотация временной сложности сознательно игнорирует члены и константы нижнего порядка. Действительно, O (n) время означает kn + c (и, возможно, другие члены младшего порядка), тогда как O (1) означает k + c, , но для разных значений k и c. Если этот алгоритм сам внутри цикла, то может быть, что O (n) будет массивно бить O (1).

Таким образом, сложность времени - это не то, что нужно учитывать здесь. То, что нужно учитывать здесь, - это , если сложность времени - это то, что нужно учитывать здесь. Если это так, то настало время посмотреть, применит ли случай O (n) O (1) из-за отсутствия накладных расходов, или следует пойти с более распространенным случаем, когда O (n) превосходит O (1), или следует ли игнорировать временную сложность и просто делать то, что читается более естественно. Например. общим случаем конкуренции по сложности времени является то, следует ли использовать список и искать его или хешированный набор и запрашивать его на основе хэша. Однако с большинством библиотек код для каждого будет выглядеть по-другому, поэтому будет один, который лучше описывает намерение, и тот, на который нужно идти, когда он не является критическим.

Важным априори, хотя и показателем производительности здесь, было то, стоит ли думать о производительности на этом этапе.

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

Итак, нам нужно подумать с самого начала, хотя на этом этапе нам не нужно все решать.

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

Еще одна разумная мысль: я уверен, что производительность этого раздела будет критической, но я пока не могу измерить влияние различных подходов. Здесь вы решили, что оптимизация, вероятно, будет необходима, но что стремление к оптимальному сейчас действительно будет преждевременным. Тем не менее, вы можете выполнить основную работу, создав свои функциональные границы, чтобы вы могли легче изменять реализацию предполагаемой критической части или, возможно, поставить код регистрации времени в эту функцию esp. на отладочных сборках и особенно. если он довольно далеко от вызывающего публичного метода (поэтому он не эквивалентен выполнению журнала времени во внешнем тесте). Здесь вы не сделали ничего априори, чтобы сделать код быстрее, но вы помогли в дальнейшем оптимизации.

Еще одна вещь, о которой разумно подумать, - это то, что нужно делать многопоточным способом, но обратите внимание на то, что есть три разумные мысли; так как это нужно будет многопрофилировать, и это не обязательно должно быть многопоточным, и этот может должен быть многопоточным. Опять же, вы можете определить функциональные границы таким образом, чтобы упростить последующую перезапись кода, чтобы этот конкретный метод вызывался параллельно с другой работой.

Наконец, вам нужно подумать о том, насколько вы сможете измерить производительность после факта и как часто вам придется.

Одним из важных случаев является то, где базовые данные будут меняться в течение всего жизненного цикла проекта. С вашим базой данных DBA вы хорошо понимаете, что оптимальное решение для определенного набора данных с определенным балансом частоты операций не одинаково для разных данных с разными рабочими частотами, даже если данные соответствуют одной и той же схеме (например, небольшая таблица тяжелые чтения и записи получат меньше выгоды от интенсивного индексирования, чем та же самая схема таблицы, в которой есть много других строк, мало записей и много сообщений). То же самое относится и к приложениям, поэтому вам нужно подумать, нужно ли вам просто делать оптимизацию на более поздней фазе оптимизации, или если вам придется часто возвращаться к оптимизации при изменении условий. В последнем случае стоит убедиться, что теперь легко изменить части, которые могут измениться в будущем.

Другим важным случаем является то, что вы не сможете легко получить информацию о том, как используется код. Если вы пишете приложение, которое используется на одном сайте, вы сможете очень хорошо его измерить. Если вы пишете приложение, которое будет распространено, это становится сложнее. Если вы пишете библиотеку, которая будет использоваться в нескольких разных приложениях, то это еще сложнее. В последнем случае аргумент о том, что YAGNI становится намного слабее; возможно, кто-то действительно нуждается в том, чтобы медленный метод был значительно улучшен, и вы не знаете об этом. Опять же, подход, который вам нужно предпринять, не всегда одинаковый; в то время как один из подходов состоит в том, чтобы приступить к работе вверх, чтобы сделать ее более успешной в этом случае (не совсем априори, поскольку она написана ранее в вашей библиотеке, но априори ее) другой подход заключается в том, чтобы просто записать, что конкретный метод по необходимости является дорогостоящим и что вызывающий код должен помнить или иным образом оптимизировать способ использования своего собственного кода , если он присваивается.

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

Ответ 21

В какой-то степени я не соглашусь с пакетом.

Вы всегда считаете производительность - но это, как правило, отклоняет ее. Посмотрите, как часто код будет работать. Если ответ "один раз" или "редко" производительность в основном не является проблемой.

Только когда часть кода будет выполняться часто, вам нужно обратить внимание на производительность. Даже в этом случае вы обычно должны смотреть только на класс O(), пока профилирование не покажет проблему.

Единственный раз, когда я буду рассматривать что-то вроде детальной оптимизации, когда я изначально пишу, - это код внутри процедуры O (scary). (Пример: тест для обеспечения того, что в наборе данных не было мертвых концов. O (n ^ 8), хотя и с существенной обрезкой. Я старался работать с первой строкой.)