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

215

Мой коллега сегодня создал класс под названием ThreadLocalFormat, который в основном переместил экземпляры классов Java Format в локальный поток, поскольку они не безопасны для потоков и «относительно дороги» в создании. Я написал быстрый тест и рассчитал, что смогу создать 200 000 экземпляров в секунду, спросил его, не создает ли он столько, на что он ответил «далеко не так много». Он отличный программист, и все в команде очень опытны, поэтому у нас нет проблем с пониманием получающегося кода, но это был случай оптимизации, когда в этом нет реальной необходимости. Он подтвердил код по моей просьбе. Как вы думаете? Это случай "преждевременной оптимизации" и насколько это плохо на самом деле?

Craig Day
источник
23
Я думаю, что вы должны различать преждевременную оптимизацию и ненужную оптимизацию. Для меня преждевременное предполагает, что «слишком рано в жизненном цикле», тогда как ненужное предполагает, «не добавляет значительной ценности». ИМО, требование поздней оптимизации подразумевает плохой дизайн.
110
Да, но зло является многочленом и имеет много корней, некоторые из них являются сложными.
dan_waterworth
7
Следует учесть, что Кнут написал это в 1974 году. В семидесятые годы писать медленные программы было не так просто, как сейчас. Он писал с мыслью о Паскале, а не о Java или PHP.
празднование
4
Нет. Корень зла - это жадность.
Тулаинс Кордова
12
@ceving В 70-х было так же легко, как сегодня, писать медленные программы. Если вы выбрали неправильный алгоритм или неправильную структуру данных, тогда BAM! Плохая производительность повсюду. Можно спорить наоборот. Сегодня это намного больше инструментов, и должно быть непростительно, что программист все еще пишет программное обеспечение, которое страдает от самой простой операции сохранения. Параллелизм стал почти товаром, и мы все еще страдаем. Низкая производительность не может быть обвинена в языке, инструменте, процессоре или памяти. Это тонкий баланс многих вещей, поэтому почти невозможно оптимизировать рано.
Алекс

Ответы:

322

Важно иметь в виду полную цитату:

Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла. Однако мы не должны упускать наши возможности в этих критических 3%.

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

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

Скотт Дорман
источник
7
Будучи от Дональда Кнута, я бы не удивился, если бы у него были какие-то доказательства, подтверждающие это. BTW, Src: Структурное программирование с переходом к заявлениям, ACM Journal Computing Surveys, том 6, № 4, декабрь 1974. с.268. citeseerx.ist.psu.edu/viewdoc/...
mctylr
28
... Хороший программист не утешится такими доводами, он посмотрит внимательно на критический код; но только после того, как этот код был идентифицирован (остаток более полной цитаты)
mctylr
21
У меня сегодня был пользователь с 20 тысячами повторений, который сказал мне, что использование HashSetвместо Listоптимизации было преждевременным. Рассматриваемый вариант использования представлял собой статически инициализированную коллекцию, единственная цель которой состояла в том, чтобы служить справочной таблицей. Я не думаю, что я ошибаюсь, говоря, что есть различие в выборе правильного инструмента для работы и преждевременной оптимизации. Я думаю, что ваш пост подтверждает эту философию: There are obvious optimizations...anything that isn't trivially clear optimization should be avoided until it can be measured.оптимизация HashSet была тщательно измерена и задокументирована.
раздавить
9
@crush: yes: Setтакже более семантически корректен и информативен List, так что здесь есть не только аспект оптимизации.
Эрик Аллик
7
Я хотел бы добавить, что преждевременную оптимизацию не следует путать с разработкой всей архитектуры приложения для быстрой работы в целом, масштабирования и простой оптимизации.
Эрик Аллик
111

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

Каковы некоторые хорошие ранние оптимизации в порядке важности:

  • Архитектурная оптимизация (структура приложения, способ его составления и многоуровневость)
  • Оптимизация потока данных (внутри и снаружи приложения)

Некоторые оптимизации середины цикла разработки:

  • Структуры данных, вводите новые структуры данных, которые имеют лучшую производительность или меньшие накладные расходы, если это необходимо
  • Алгоритмы (сейчас самое время начать выбирать между quicksort3 и heapsort ;-))

Некоторые оптимизации в конце цикла разработки

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

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

Если производительность вызывает беспокойство (и всегда должно быть), всегда мыслить масштабно . Производительность - это большая картина, а не такие вещи, как: использовать ли int или long ? Перейти к списку вниз при работе с производительностью , а не снизу вверх .

Pop Catalin
источник
«Оптимизация: ваш худший враг», Джозеф М. Новичок: flounder.com/optimization.htm
Рон Рубль
53

оптимизация без первого измерения почти всегда преждевременна.

Я считаю, что это верно в этом случае, и верно в общем случае.

Джефф Этвуд
источник
Здесь, здесь! Необдуманная оптимизация делает код необслуживаемым и часто является причиной проблем с производительностью. Например, вы используете многопоточную программу, потому что вы думаете, что она может повысить производительность, но реальным решением были бы несколько процессов, которые сейчас слишком сложны для реализации.
Джеймс Андерсон
если это не задокументировано.
nawfal
Да. полностью согласен. Сначала нужно измерить. Невозможно узнать, где находятся узкие места, пока вы не протестируете что-либо из конца в конец и не измерите каждый из шагов.
Оливер Уоткинс,
Измерения могут лгать. Я видел, как опытные специалисты проводят недели, читая следы и запуская профили, чтобы попасть в стену, где они думают, что больше нечего получить. Затем я перечитал весь код и через несколько часов внес несколько целостных изменений, чтобы получить улучшение в 10 раз. Профили не показывали горячих путей, потому что весь код был плохо спроектирован. Я также видел, как профилировщики заявляют о горячих путях там, где их не должно было быть. Человек, «измеряющий», оптимизировал бы горячую тропу, но он должен был понять, что горячая тропа была признаком другого плохого кода.
Бенги
42

Оптимизация является «злом», если она вызывает:

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

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

Джон Малдер
источник
4
Только если стоимость, в пересчете на ваши пункты маркера, больше амортизированной стоимости. Часто сложность привносит ценность, и в этих случаях можно инкапсулировать ее так, чтобы она соответствовала вашим критериям. Он также используется повторно и продолжает обеспечивать большую ценность.
1
Эти первые два пункта являются главными для меня, а четвертый пункт является негативным следствием преждевременной оптимизации. В частности, это красный флаг, когда я вижу, как кто-то повторно реализует функции из стандартной библиотеки. Например, я однажды видел, как кто-то реализовывал пользовательские процедуры для работы со строками, потому что он был обеспокоен тем, что встроенные команды были слишком медленными.
Джокинг
8
Обеспечение безопасности потока кода не является оптимизацией.
Mattnz
38

Я удивлен, что этому вопросу 5 лет, и все же никто не опубликовал больше того, что должен был сказать Кнут, чем пару предложений. Пара абзацев, окружающих известную цитату, объясняют это довольно хорошо. Цитируемый документ называется « Структурированное программирование с переходом к утверждениям », и, хотя ему уже почти 40 лет, он посвящен спорам и программному движению, которого больше нет, и есть примеры на языках программирования, которых многие люди никогда не видели слышал о, удивительно большое количество того, что он сказал, все еще применяется.

Вот большая цитата (со страницы 8 в pdf, страница 268 в оригинале):

Улучшение скорости от примера 2 к примеру 2а составляет всего около 12%, и многие люди считают это незначительным. Общепринятая мудрость, разделяемая многими современными разработчиками программного обеспечения, требует игнорирования эффективности в малом; но я полагаю, что это просто чрезмерная реакция на злоупотребления, которые, как они видят, практикуются программистами, которые не могут отлаживать или поддерживать свои «оптимизированные» программы. В устоявшихся инженерных дисциплинах легко достижимое улучшение на 12% никогда не считается незначительным; и я считаю, что та же точка зрения должна преобладать в разработке программного обеспечения. Конечно, я бы не стал делать такую ​​оптимизацию на одноразовой работе, но когда речь идет о подготовке качественных программ, я не хочу ограничиваться инструментами, которые лишают меня такой эффективности.

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

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

Еще один хороший момент с предыдущей страницы:

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

Майкл Шоу
источник
20

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

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

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

Таким образом, в целом, я думаю, что правильный подход состоит в том, чтобы выяснить, какие у вас есть варианты, прежде чем вы начнете писать код, и сознательно выбрать лучший алгоритм для вашей ситуации. Самое главное, что фраза «преждевременная оптимизация - корень всего зла» не оправдывает невежество. Карьерный разработчик должен иметь общее представление о том, сколько стоят общие операции; они должны знать, например,

  • что строки стоят больше, чем числа
  • что динамические языки намного медленнее, чем языки со статической типизацией
  • преимущества списков массивов / векторов над связанными списками и наоборот
  • когда использовать хеш-таблицу, когда использовать отсортированную карту и когда использовать кучу
  • что (если они работают с мобильными устройствами) «double» и «int» имеют одинаковую производительность на настольных компьютерах (FP может быть даже быстрее), но «double» может быть в сто раз медленнее на мобильных устройствах низкого уровня без FPU;
  • что передача данных через Интернет происходит медленнее, чем доступ к жестким дискам, жесткие диски значительно медленнее, чем ОЗУ, ОЗУ намного медленнее, чем кэш-память L1 и регистры, а операции в Интернете могут блокироваться бесконечно (и в любой момент завершиться сбоем).

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

Обладая достаточными знаниями и личным инструментарием, вы можете оптимизировать работу практически без усилий. Вкладывать много усилий в оптимизацию, которая может оказаться ненужной, - зло (и я признаю, что попадал в эту ловушку не раз). Но если оптимизация так же проста, как выбор набора / хеш-таблицы вместо массива или сохранение списка чисел в double [] вместо string [], то почему бы и нет? Возможно, я не согласен с Кнутом здесь, я не уверен, но я думаю, что он говорил об оптимизации низкого уровня, тогда как я говорю об оптимизации высокого уровня.

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

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

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

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

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

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

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

Шейн Маклафлин
источник
Это конечно правильно. Я предполагаю, что преждевременная оптимизация - это когда код становится более сложным / трудным для понимания с неясными преимуществами, причем таким образом, что он имеет только локальное влияние (дизайн оказывает глобальное влияние).
Поль де Вриз
2
Все дело в определениях. Я использую оптимизацию как проектирование и написание кода для оптимальной работы. Большинство из них, похоже, считают, что он взломал код после того, как обнаружил, что он недостаточно быстр или эффективен. Я трачу много времени на оптимизацию, обычно во время проектирования.
3
Оптимизируйте дизайн в начале, Оптимизируйте код в конце.
БКС
Вы совершенно правы в своем случае, однако для большинства программистов они считают, что столкнутся с проблемами производительности, но в действительности они никогда не будут. Многие беспокоятся о производительности при работе с 1000 сущностями, когда базовый тест на данных покажет, что производительность в порядке, пока они не достигнут 1000000 сущностей.
Тоби Аллен
1
«Планирование оптимальной производительности на этапе проектирования намного лучше, чем поздняя оптимизация слабого дизайна», а «поздняя оптимизация обеспечивает скудные выгоды по высокой цене», что очень хорошо! Вероятно, это не так для 97% всех производимых систем, но это для многих систем, которые приводят в замешательство.
Олоф Форшелл
10

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

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

Все это, кроме производительности. Кажется, никто не заботится о производительности. Причина проста: если происходит сбой программного обеспечения, кто-то исправит ошибку, и все, если какая-то функция отсутствует, кто-то ее реализует и сделает, если программное обеспечение имеет плохую производительность, это во многих случаях не из-за отсутствия микрооптимизации, а из-за плохого дизайна и никто не собирается трогать дизайн программного обеспечения. КОГДА-ЛИБО.

Посмотри на Бохса. Это медленно, как ад. Будет ли это когда-нибудь быстрее? Может быть, но только в пределах нескольких процентов. Он никогда не достигнет производительности, сравнимой с программным обеспечением для виртуализации, таким как VMWare, VBox или даже QEMU. Потому что это медленно по дизайну!

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

Поэтому, если производительность ЛЮБОГО важна для вашего программного обеспечения, вы должны принимать это во внимание с самого начала, при проектировании, вместо того, чтобы думать: «О, да, это медленно, но мы можем улучшить это позже». Потому что ты не можешь!

Я знаю, что это не совсем соответствует вашему конкретному случаю, но отвечает на общий вопрос: «Действительно ли преждевременная оптимизация - корень всего зла?» - с явным НЕТ.

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

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

Глупая оптимизация является более злой, чем «преждевременная» оптимизация, но обе они все же лучше, чем преждевременная неоптимизация

комара
источник
6

С ПО есть две проблемы: во-первых, время разработки используется для несущественной работы, которую можно использовать для написания большего количества функций или исправления большего количества ошибок, и во-вторых, ложное чувство безопасности, что код работает эффективно. PO часто включает в себя оптимизацию кода, который не будет узким местом, при этом не замечая код, который будет. Бит «преждевременный» означает, что оптимизация выполняется до того, как проблема идентифицируется с использованием надлежащих измерений.

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

harriyott
источник
Вы хотите сказать «писать больше тестов» вместо «писать больше функций», верно? :)
Грег Хьюгилл
1
больше возможностей влечет за собой больше тестов :)
workmad3
Э, да! Это именно то, что я имел в виду ...
Harriyott
2
Код вносит дополнительную сложность и, вероятно, не будет использоваться повсеместно. Поддержка (и тому подобное) сохраняет код в чистоте.
Поль де Вриз
3

Я полагаю, что это то, что Майк Кон называет «позолотой» кода - т. Е. Тратить время на вещи, которые могут быть хорошими, но не обязательными.

Он посоветовал против этого.

PS «Позолота» может быть специфической функциональностью. Когда вы смотрите на код, он принимает форму ненужной оптимизации, «ориентированных на будущее» классов и т. Д.

Илья Кочетов
источник
2
Я думаю, что «позолота» отличается от оптимизаций. Как правило, оптимизация - это попытка получить максимальную производительность, в то время как «позолота» - это добавление «наворотов» (всей дополнительной функциональности), которые не являются критичными для продукта, но выглядят / выглядят круто.
Скотт Дорман
3

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

Но в целом оптимизация приводит к менее читаемому и менее понятному коду и должна применяться только при необходимости. Простой пример - если вы знаете, что вам нужно отсортировать только пару элементов - используйте BubbleSort. Но если вы подозреваете, что количество элементов может увеличиться, а вы не знаете, сколько, оптимизация с помощью QuickSort (например) - это не зло, а необходимость. И это следует учитывать при разработке программы.

m_pGladiator
источник
1
Не согласна Я бы сказал, никогда не используйте пузырьковую сортировку. Quicksort стал стандартом де-факто и хорошо понятен, и его так же легко внедрить, как пузырьковую сортировку во всех сценариях. Самый низкий общий знаменатель уже не так уж низок;)
1
Для действительно небольшого количества элементов рекурсия, необходимая для быстрой сортировки, может сделать ее медленнее, чем приличная пузырьковая сортировка, хотя ... не говоря уже о том, что пузырьковая сортировка быстрее в худшем сценарии быстрой сортировки (а именно, быстрой сортировке отсортированного списка)
workmad3
да, но это всего лишь пример того, как выбирать алгоритмы для различных нужд;)
Правда, но я бы выбрал быструю сортировку в качестве сортировки по умолчанию. Если бы я думал, что пузырьковая сортировка улучшит производительность, это будет оптимизация, а не наоборот. Я по умолчанию выбираю быструю сортировку, потому что она понятна и в целом лучше.
2
Моя идея сортировки по умолчанию - это то, что дает мне библиотека (qsort (), .sort (), (sort ...), что угодно).
Дэвид Торнли
3

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

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

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

jhocking
источник
3

С другой точки зрения, по моему опыту, большинство программистов / разработчиков не планируют успеха, и «прототип» почти всегда становится Release 1.0. Я имею непосредственный опыт работы с 4 отдельными оригинальными продуктами, в которых стильный, сексуальный и высоко функциональный интерфейс (в основном пользовательский интерфейс) привел к широкому распространению пользовательского признания и энтузиазма. В каждом из этих продуктов проблемы производительности начали появляться в течение относительно коротких промежутков времени (от 1 до 2 лет), особенно когда более крупные и требовательные клиенты начали внедрять этот продукт. Очень скоро производительность доминировала в списке проблем, хотя разработка новых функций доминировала в списке приоритетов менеджмента. Клиенты становились все более и более разочарованными, поскольку в каждом выпуске добавлялись новые функции, которые звучали великолепно, но были почти недоступны из-за проблем с производительностью.

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

Демонстрация вашего клиента может отлично выглядеть и работать на вашем ноутбуке с XML DOM, SQL Express и большим количеством кэшированных данных на стороне клиента. Производственная система, вероятно, вылетит, если вы добьетесь успеха.

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

Когда кто-то повторяет эту пословицу в качестве оправдания за то, что он не пишет эффективный код (C ++, VB, T-SQL или иным образом), или за неправильное проектирование хранилища данных, или за то, что он не рассматривает архитектуру сетевой работы, тогда IMO просто демонстрируют очень поверхностное понимание реального характера нашей работы. луч

луч
источник
1
Ха-ха, или когда демо с тремя пользователями становится релизом 1.0 с тысячей.
Олоф Форшелл
1

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

Доминик Роджер
источник
1

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

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

Примером, который я могу описать, является модель данных, которую я однажды сделал для системы управления делами в суде, в которой было около 560 таблиц. Сначала все нормализовалось («красиво нормализовано», как выразился консультант из одной крупной пятерки), и нам нужно было поместить в него только четыре элемента денормализованных данных:

  • Один материализованный вид для поддержки экрана поиска

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

  • Одна денормализованная таблица отчетов (она существовала только потому, что нам приходилось брать некоторые отчеты о пропускной способности, когда проект хранилища данных был закрыт)

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

Это был (в то время) крупнейший проект J2EE в Австралии - более 100 лет времени разработки - и в схеме базы данных было 4 денормализованных элемента, один из которых на самом деле не принадлежал вообще.

ConcernedOfTunbridgeWells
источник
1

Преждевременная оптимизация не является корнем ВСЕГО зла, это точно. Есть, однако, недостатки этого:

  • Вы тратите больше времени на разработку
  • вы тратите больше времени на его тестирование
  • Вы тратите больше времени на исправление ошибок, которых в противном случае не было бы

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

Herr_Alien
источник
1

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

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

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

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

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

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

Посмотрите на эту превосходную статью о том, что PMO может или не может означать.

Олоф Форшелл
источник