Я сталкивался со многими людьми, которые догматично настроены против всего, что можно считать «оптимизацией» в общем англоязычном смысле этого слова, и они очень часто цитируют дословно (частичную) цитату «преждевременная оптимизация - корень всего зла». в качестве оправдания своей позиции, подразумевая, что они интерпретируют все, о чем я говорю, как «преждевременную оптимизацию». Тем не менее, эти представления иногда настолько нелепо укоренились, что они отклоняют практически любые отклонения алгоритмического или структурного характера от самой «наивной» реализации ... или, по крайней мере, любые отклонения от того, как они делали вещи раньше.Как можно подойти к таким людям так, чтобы они снова «открыли уши» после того, как они перестали слышать о «производительности» или «оптимизации»? Как мне обсудить тему проектирования / реализации, которая влияет на производительность, не заставляя людей сразу думать: «Этот парень хочет потратить две недели на десять строк кода?»
Теперь позиция того, является ли «всякая оптимизация преждевременной и, следовательно, злой» или нет, уже освещалась здесь, а также в других уголках сети , и уже обсуждалось, как распознать, когда оптимизация преждевременна и, следовательно, зла , но к сожалению, в реальном мире все еще есть люди, которые не настолько открыты для вызовов своей вере в антиоптимизацию.
Предыдущие попытки
Несколько раз я пытался предоставить полную цитату от Дональда Кнута , чтобы объяснить, что «преждевременная оптимизация плоха», «вся оптимизация плоха»:
Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла. Однако мы не должны упускать наши возможности в этих критических 3%.
Однако при предоставлении всей цитаты эти люди иногда на самом деле становятся более убежденными в том, что я занимаюсь преждевременной оптимизацией ™, копаются и отказываются слушать. Это почти как если бы слово «оптимизация» пугало их: в нескольких случаях я смог предложить реальные изменения кода, улучшающие производительность, без наложения на них вето, просто избегая использования слова «optimiz (e | ation)» ( а также «производительность» - это слово тоже страшно) и вместо этого используется какое-то выражение, например «альтернативная архитектура» или «улучшенная реализация». По этой причине действительно кажется, что это действительно догматизм, а не то, что они на самом деле оценивают то, что я говорю, критически, а затем отвергаем это как ненужное и / или слишком дорогое.
источник
Ответы:
Похоже, вы ищете ярлыки, чтобы сначала не попробовать «чистейшую наивную реализацию», а напрямую реализовать «более сложное решение, потому что вы заранее знаете, что наивная реализация этого не сделает». К сожалению, это будет редко работать - когда у вас нет веских фактов или технических аргументов, чтобы доказать, что наивная реализация слишком медленная или слишком медленная, вы, скорее всего, ошибаетесь, а то, что вы делаете, - это преждевременная оптимизация. И попытка спорить с Кнутом - противоположность того, чтобы иметь жесткий факт.
По моему опыту, вам либо придется сначала прикусить пулю и попробовать «наивную реализацию» (и, вероятно, вы будете удивлены, насколько часто это происходит достаточно быстро), либо вы, по крайней мере, сделаете приблизительную оценку времени выполнения, например:
«Наивной реализацией будет O (n³), а n больше 100.000; она будет работать несколько дней, в то время как не столь наивная реализация будет работать в O (n), что займет всего несколько минут» .
Только с такими аргументами вы можете быть уверены, что ваша оптимизация не преждевременна.
ИМХО есть только одно исключение из этого: если более быстрое решение также является более простым и чистым, вам следует использовать более быстрое решение с самого начала. Стандартный пример - использование словаря вместо списка, чтобы избежать ненужного кода цикла для поиска, или использование хорошего SQL-запроса, который дает именно одну нужную запись результата, а не большой набор результатов, который должен быть затем фильтруется в коде. Если у вас есть такой случай, не спорьте о производительности - производительность может быть дополнительным, но, скорее всего, несущественным преимуществом, и когда вы упомянете об этом, у людей может возникнуть соблазн использовать Кнут против вас. Спорьте о читабельности, более коротком коде, более чистом коде, удобстве обслуживания - здесь не нужно «маскировать» что-либо, но потому что эти (и только те) являются правильными аргументами здесь.
По моему опыту, последний случай редок - более типичным является случай, когда сначала можно реализовать простое, наивное решение, которое более понятно и менее подвержено ошибкам, чем более сложное, но, вероятно, более быстрое.
И, конечно, вы должны знать требования и пример использования достаточно хорошо, чтобы знать, какая производительность приемлема и когда ситуация становится «слишком медленной» в глазах ваших пользователей. В идеальном мире ваш клиент получил бы официальную спецификацию производительности, но в реальных проектах требуемая производительность часто является серой областью, о которой ваши пользователи скажут вам, только когда заметят, что программа ведет себя «слишком медленно» в работе. И часто это единственный рабочий способ выяснить, когда что-то идет слишком медленно - обратная связь с пользователем, и тогда вам не нужно ссылаться на Кнута, чтобы убедить своих товарищей по команде, что их «наивной реализации» было недостаточно.
источник
Задай себе вопрос:
Это причины для оптимизации. Так что, если люди против, просто покажите им спецификацию, вернитесь к ним и объясните, что мы должны оптимизировать, потому что мы не отвечаем спецификациям. Кроме этого, было бы трудно убедить других, что оптимизация необходима.
Я думаю, что основной смысл цитаты в том, что если у вас нет проблем, не выполняйте ненужную оптимизацию, поскольку время и энергия могут быть потрачены в другом месте. С точки зрения бизнеса это имеет смысл.
Во-вторых, для тех, кто боится оптимизации, всегда подкрепляйте полученные результаты показателями. Насколько быстрее код? Насколько производительность улучшилась по сравнению с предыдущими? Если бы я потратил две недели только на то, чтобы улучшить код на 2% по сравнению с предыдущей версией, я бы не стал вашим боссом. Эти две недели можно было бы потратить на внедрение новой функции, которая могла бы привлечь больше клиентов и заработать больше денег.
Наконец, большая часть программного обеспечения не должна быть сильно оптимизирована. Только в нескольких специализированных отраслях скорость действительно важна. Таким образом, большую часть времени можно использовать уже существующие библиотеки и фреймворки с хорошим эффектом.
источник
Начните с общих принципов, которые строятся на стратегическом направлении вашей группы.
Мои принципы:
Мои личные принципы написания кода - сначала стремиться к корректности в моей программе, а затем профилировать ее и определять, нуждается ли она в оптимизации. Я сам профилирую свой код, потому что другие программисты являются потенциальными потребителями моего кода - и они не будут использовать его, если он медленный - поэтому для моего кода скорость - это особенность.
Если ваши потребители являются клиентами, ваши клиенты скажут вам, если вам нужен более быстрый код.
Тем не менее, существуют известные, явно лучшие варианты кода, которые можно сделать. Я предпочел бы сделать это правильно в моем первом проекте по нескольким причинам:
Предполагая, что потребность в оптимизации является правильной
Предполагая, что это действительно важная часть вашего кода, которая нуждается в оптимизации, вы можете рассказать притчу о Шлемиле-рисовальщике или подчеркнуть оставшуюся часть цитаты:
Взвесьте расходы дополнительной сложности
Иногда существует реальная стоимость с точки зрения ремонтопригодности добавленной сложности. В этом случае вы можете оставить вторичную реализацию в другой функции или подклассе и применить к ней те же самые юнит-тесты, чтобы не было сомнений в ее правильности. Позже, если вы профилируете свой код и обнаружите, что наивная реализация является узким местом, вы можете включить оптимизированный код и явно улучшить свою программу.
руководство
Иногда проблема заключается в эго - некоторые люди предпочитают использовать неоптимальный или ошибочный код, чем когда кто-то более прав, чем они. Вы, вероятно, хотите избежать работы с этими людьми.
Лидерство, особенно когда у вас нет позиционной власти над людьми, заключается в том, чтобы делать разумные предложения и направлять других к консенсусу. Если вы не можете направить свою команду на встречу умов, возможно, этот вопрос не стоит называть. Вероятно, есть рыба побольше.
источник
Путь вперед состоит в том, чтобы забыть о фактической цитате и различных интерпретациях - если это догматизм, так или иначе, сосредоточиться так сильно на конкретной цитате гуру. Кто сказал, что Кнут всегда прав?
Вместо этого сосредоточьтесь на проекте под рукой, программном обеспечении, которое вы разрабатываете вместе с коллегами, с которыми вы не согласны. Каковы требования для приемлемой производительности для этого программного обеспечения? Это медленнее, чем это? Тогда оптимизируйте.
Вам не нужно называть это «оптимизацией», вы можете называть это «исправлением ошибки», поскольку по определению это ошибка, если реализация не соответствует требованиям.
В целом, есть две возможности в отношении оптимизации:
Оптимизированный код также короче, проще для понимания и проще в обслуживании.
Оптимизированный код более сложен для понимания, требует больше времени для написания и тестирования или будет более сложным для изменения в будущем, если требования изменятся неожиданным образом.
Если случай (1), вам даже не нужно спорить об оптимизации. Но если (2) имеет место, то вы участвуете в компромиссном решении. Это на самом деле решение бизнес-уровня, а не чисто техническое решение. Вы должны сопоставить стоимость оптимизации с выгодой. Для того, чтобы была даже какая-то выгода, неэффективность должна быть проблемой в первую очередь, либо из-за плохого пользовательского опыта, либо из-за значительного увеличения стоимости оборудования или других ресурсов.
источник
Я думаю, что полная цитата в контексте поучительна. Я скопирую из поста, который я сделал на Reddit по теме:
- Дональд Кнут, Структурное программирование с переходом к заявлениям , ACM Computing Surveys, том 6, № 4, декабрь 1974 года, с.268
Суть и следствие в том, что есть более важные вещи, о которых нужно беспокоиться, чем слишком рано обращать внимание на оптимизацию. Конечно, вы должны внимательно рассмотреть свои структуры данных и алгоритмы (это в 3%), но вам не следует беспокоиться о том, происходит ли вычитание быстрее, чем по модулю (это в 97%), пока не станет ясно, что низкоуровневая оптимизация необходимо.
Первое - это не обязательно оптимизация в том смысле, в каком думают ваши коллеги, но это оптимизация в том смысле, что плохо выбранные алгоритмы и структуры данных являются неоптимальными.
источник
По моему опыту, если вы регулярно сталкиваетесь с такой оптимизацией , люди на самом деле не жалуются на оптимизацию. Они жалуются на то, чем вы жертвуете во имя оптимизации. Обычно это удобочитаемость, ремонтопригодность или своевременность. Если ваш код доставляется за такое же время и так же просто для понимания, людям будет все равно, если вы используете более эффективные структуры данных и алгоритмы. Мое предложение в этом случае - поработать над тем, чтобы сделать ваш код более элегантным и понятным.
Если вы получаете такую оппозицию в отношении кода других людей, обычно это потому, что вы предлагаете значительное количество переделок. В этих случаях вам действительно нужны некоторые реальные измерения, чтобы показать, что это стоит затраченных усилий, или, возможно, попытаться принять участие на более ранней стадии разработки, прежде чем код будет написан. Другими словами, вам нужно доказать, что это в 3%. Если бы мы переписали весь код, который был не совсем таким, каким он нам нравился, мы бы никогда ничего не достигли.
источник
Deque
стандартную библиотеку Java, чтобы заменить огромное количество логики, построенной наArrayList
использовании в качестве стека при работе с кодом ... и это было отмечено для изменить в обзоре. Другими словами, рецензент хотел иметь больше кода, который также медленнее и более подвержен ошибкам, потому что он не был знаком с нимDeque
.В этой цитате действительно много недоразумений, поэтому лучше сделать шаг назад и посмотреть, что же это за проблема. Проблема не в том, что вы никогда не должны «оптимизировать». Дело в том, что «оптимизировать» никогда не стоит перед вами. Вы никогда не должны просыпаться утром и говорить себе: «Эй, я должен оптимизировать код сегодня!».
Это приводит к напрасным усилиям. Просто смотрю на код и говорю: «Я могу сделать это быстрее!» приводит к огромным усилиям по созданию чего-то более быстрого, что было достаточно быстрым в первую очередь. Вы можете гордиться тем, что говорите себе, что вы сделали немного кода в четыре раза быстрее, но если этот код был вычислением, которое происходило при нажатии кнопки, и потребовалось 10 мсек, прежде чем показывать пользователю, никто собирается наплевать.
Это «преждевременный» в «преждевременной оптимизации». Когда это не «преждевременно»? Когда клиенты говорят вам "это слишком медленно, исправьте это!" Вот когда вы копаете код и пытаетесь сделать его быстрее.
Это не значит, что вы должны выключить свой мозг. Это не значит, что вы должны хранить 10 000 записей клиентов в единственном связанном списке. Вы всегда должны понимать влияние на производительность того, что вы делаете, и действовать соответственно. Но идея в том, что вы не тратите дополнительное время на то, чтобы сделать это быстрее. Вы просто выбираете более производительный выбор из других равных вариантов.
источник
Вы можете делать что-то неправильно или делать все правильно.
Часто все делается неправильно, а код реорганизуется так, что все делается правильно. Если вы собираетесь писать новый код, и вы знаете, что вы можете делать все правильно, без серьезного штрафа, я бы просто ошибся в правильном подходе. (Обратите внимание, что после тестирования производительности и т. Д. Некоторые вещи, возможно, должны измениться, но это нормально. Альтернативно, совершенно наивная реализация редко, если вообще когда-либо, правильна.)
Это не обязательно преждевременная оптимизация, если вы а) знаете, что это поможет в будущем, или б) знаете, что неоптимальный путь приведет к проблемам в будущем. Это как игра в шахматы, правда.
Я думаю, что люди будут стремиться делать что-то правильно, а не делать это неправильно. Используйте это, когда обсуждаете альтернативные стратегии со своими сверстниками.
источник
Это похоже на проблему со связью, а не проблему программирования. Постарайтесь понять, почему люди чувствуют то, что они делают, и попытаться понять, почему вы думаете, что ваш путь будет лучше. Когда вы это сделаете, не начинайте конфронтационный спор, где ваша цель - рассказать другим, почему они неправы, а вы правы. Объясните свои мысли и чувства и просто позвольте людям реагировать на это. Если вы не можете прийти к какому-либо консенсусу и чувствуете, что это действительно очень важный вопрос, то, возможно, у вас в команде есть серьезные проблемы.
Больше сосредотачивайтесь на реальном программировании, не тратьте время на долгие споры из-за того, что у вас есть интуитивное чувство «быстрее». Если вы видите, что кто-то пишет метод, который вызывается один раз для каждого запроса в веб-приложении, и у него есть O (n ^ 2) временная сложность, когда вы ЗНАЕТЕ, что это действительно O (log (n)) временная проблема, то конечно, если это так ежу понятно, давай.
Однако помните, что как люди, мы, программисты, действительно плохо (и я имею в виду УЖАСНОЕ) угадывать, какие части наших приложений будут узким местом. Эрик Липперт пишет об этой интересной теме в этом посте. Всегда одобряйте ремонтопригодность. Любые проблемы с производительностью, которые в конечном итоге обнаруживаются, могут быть легко (ну, относительно) исправлены, когда у вас будет больше информации.
источник