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

Я, кажется, замечаю две мысли о том, что происходит в оптимизации:

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

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

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

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

Оптимизируйте на уровне проектирования и архитектуры на ранней стадии. Микро-оптимизация на уровне реализации позже.

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

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

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

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

Существует также разработка эффективных навыков кодирования при выборе между двумя другими подобными практиками. Например, в C ++ стоит написать ++i а не i++ , потому что это тривиальная вещь, которая иногда может быть значительно более эффективной.

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

Адаптация цитаты «это тактика, если вы выиграете, и это изменяет, если вы проиграете», я бы сказал

Это «планирование эффективности», если это сработало, и это «преждевременная оптимизация», если это не так.

Мне нравится этот парень .

  1. Оптимизация с использованием более разумного общего подхода.
  2. Оптимизация, делая код менее странным.
  3. Оптимизация, делая код более странным.

Первые два – это пункт 2. Его 3 – это ваш 1 и тот, который является корнем всего зла. И он прав, оптимизация, которая делает код «более странным», усложняет и усложняет понимание, приводя к большему количеству ошибок и головной боли обслуживания.

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

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

  1. Знайте, как работают все стандартные контейнеры, на что они хороши и на что они вредны. например. SortedDictionary быстро вставляет и выполняет поиск, но плохо при удалении. LinkedList быстро добавляет и удаляет, но плохо работает при поиске и т. Д.
  2. Знайте, где будут ваши шеи бутылки. Будут ли они процессором, диском, памятью, графикой, IO, сетью и т. Д. Знайте, как эффективно использовать каждую из них, каждая область требует разных шаблонов проектирования. Это действительно зависит от того, как разрабатывается приложение: какова основная метрика, на которую нужно сосредоточиться, для обеспечения пользовательского интерфейса, для обработки данных хорошего кэширования дисков.
  3. Multhreading. Если приложение будет масштабироваться до нескольких ядер, его необходимо решить очень рано в жизненном цикле разработки, если такая система необходима. Закрепление резьбы на более позднем этапе намного более дорогостоящее.

Некоторые из ответов, которые вы будете знать по опыту, некоторые потребуют исследований, но они никогда не будут угадывать работу.

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

Существует одна основная истина:

Вы не можете оптимизировать то, что вы не можете проверить

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

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

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

Базы данных, в частности, нелегко реорганизовать и часто являются самым большим узким местом в системе из-за дизайнеров, которые думают, что им не нужно заботиться о производительности при их разработке. Это недальновидно. Существует много известных оптимизаций баз данных, которые почти все время будут быстрее. Не использовать их в своем дизайне и интуитивном кодировании, чтобы избежать «преждевременной оптимизации», является глупым. Например, курсор почти никогда (если вы не ищете текущие итоги) лучше работает, чем запрос на основе набора в SQl Server. Записывать курсор вместо запрограммированного набора не быстрее (как только вы понимаете запросы на основе набора), поэтому нет оснований начинать с кода на основе курсора. То же самое происходит с производными таблицами. Зачем писать код, который, как вы знаете, 90% времени будет медленнее, чем другой код, который занимает столько же времени, чтобы писать?

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

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

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

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

Код, помимо предоставления базовой функциональности, имеет еще три функции, которые разработчик программного обеспечения должен предоставить:

  1. Представление
  2. Ремонтопригодность
  3. прочность

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

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

Моя теория гласит: «Напишите простой рабочий код, а затем оптимизируйте его по мере необходимости».

Давайте будем гением компьютера.