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


178

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

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

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

Факторы окружающей среды могут быть важны - Интернет потребляет 10% мировой энергии. Интересно, насколько расточительны несколько микросекунд кода, когда триллионы раз тиражируются на миллионах сайтов?

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

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

Мое личное резюме из 25 ответов, спасибо всем.

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

if (expensiveFunction() || counter < X)

Должно быть

if (counter < X || expensiveFunction())

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


123
Совет твоего отца устарел . Я бы не спрашивал, насколько это улучшает производительность. Я бы спросил, где узкое место. Неважно, если вы улучшите производительность раздела кода, если это не имеет общего значения, ваша самая медленная ссылка определит скорость. В PHP это запись в сеть (если вы не можете доказать, что IE измеряет иначе); который переводит в написание более читаемого кода, более важен.
Мартин Йорк,

61
Если ключевое слово считать, он не ошибается. Вы должны иметь некоторое представление об этом.
JeffO

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

13
Можете ли вы предоставить источник "10% мировой энергии"?
Майкл Пасха

17
coder does not consider performance in their code even at the micro level, they are not good programmersсильно отличается от микрооптимизации. Это просто хорошее кодирование.
woliveirajr

Ответы:


90

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

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

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

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

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

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


120

Микрооптимизация важна, только если цифры говорят, что это так.

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

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


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

7
@ Маврик Это правда. Если у вас есть две функции, X и Y, и Y быстрее, чем X (по крайней мере, для ваших конкретных условий), нет никаких оснований не использовать Y, если код по-прежнему читаем и поддерживается. Но если вы не знаете о Y и вам нужно реорганизовать код, чтобы использовать Y вместо X, а производительность (этого сегмента кода) не является проблемой, то нет причин вносить это изменение. Все дело в компромиссах - производительности, времени, затратах, усилиях, удобочитаемости / удобстве обслуживания и так далее.
Томас Оуэнс

2
Я полностью согласен, я просто хотел высказать это, когда речь заходит о микрооптимизации - если это вам ничего не стоит с точки зрения читаемости / времени, сделайте это. В противном случае нет.
Маврик

+1 высокооптимизированный код менее читаемый и обслуживаемый ... но не всегда.
Boz

Больше случаев, когда важна производительность: (1) игры; (2) большие объемы данных; (3) веб-сайт с высокой посещаемостью; (4) отзывчивость очень сложного пользовательского интерфейса; (5) сервис, который должен работать в фоновом режиме, как проверка на вирусы; (6) финансы; (7) смартфон; и так далее. Едва ли это ограничивается эзотерическими случаями, такими как RTS и встроенные системы.
Рекс Керр

103

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

Первое правило оптимизации программы: не делайте этого.

Второе правило оптимизации программы (только для экспертов!): Пока не делайте этого .

Цитата из Википедии с поправкой на британский английский. * 8' )

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

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

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

Если вы не знакомы с большой частью того, о чем говорит Ульрих Дреппер в своей превосходной статье « Что должен знать каждый программист о памяти» , то вы, вероятно, проиграли, даже пытаясь оптимизировать себя. Однако, вопреки названию статей (что на самом деле является данью уважения столь же фантастическому Дэвиду Голдбергу, что должен знать каждый учёный-компьютерщик об арифметике с плавающей точкой ), отсутствие такого уровня понимания не обязательно мешает вам быть хорошим программистом, просто другой вид программист.

isset()против strlen()в PHP

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

Не только это, но и нет никакой гарантии, что isset()она всегда будет более эффективной, просто потому, что сейчас она более эффективна. Оптимизация сейчас может не быть оптимизацией в следующем году или через 10 лет. Процессоры, системы, компиляторы улучшаются и изменяются со временем. Если производительность PHP strlen()является проблемой, PHP может измениться в будущем, тогда, возможно, придется удалить все оптимизации isset (), чтобы еще раз оптимизировать код.

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

Пример из личного опыта

В качестве примера такой антиоптимизации я однажды должен был очистить огромную кодовую базу, заполненную кодом формы, if x==0 z=0 else z=x*yпотому что кто-то предположил, что умножение с плавающей запятой всегда будет дороже, чем ветвь. В исходной целевой архитектуре эта оптимизация заставила код работать на порядок быстрее, но времена меняются.

Когда мы попытались использовать этот код на более современном процессоре с высокой степенью конвейеризации, производительность была ужасно плохой - каждое из этих утверждений вызывает сброс конвейера. Упрощение всех этих строк кода для z=x*yускорения работы программы на новой архитектуре на порядок выше, восстанавливая производительность, потерянную антиоптимизацией .

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

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


3
Трубопроводная очистка и потеря кэша - это то, чего вы хотите избежать: D У них ужасные затраты. но только на части кода, которые оправдывают их много много много много много раз.
Deadalnix

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

3
+1 за реальный пример микрооптимизации, которая потратила впустую время, и за то, что Майкл Джексон был программистом.
Boz

1
+1 За пример. Это прекрасно иллюстрирует, почему вы должны оставить тривиальные преобразования для компилятора.
back2dos

1
@Rex Kerr> в приведенном примере стоимость исходит от ветвления, что приводит к сбросу конвейера ЦП. Умножение с плавающей запятой тоже дорого. То, что является более дорогим, сильно зависит от FPU и длины конвейера процессора, на котором выполняется код. Я не удивлюсь, что этот код работает быстрее на старых процессорах, которые имеют более короткий конвейер и менее эффективный FPU, чем текущий процессор.
Deadalnix

84
  1. Напишите код, который будет чистым, лаконичным, простым и понятным.
  2. Проведите тесты производительности для выявления узких мест.
  3. Оптимизировать критические разделы.

Как правило: 95% вашего кода выполняется 5% времени. Нет смысла оптимизировать, пока вы не профилируете / не протестируете свой код и не увидите, какие 5% работают в 95% случаев.

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

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

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


2
Лучший ответ для меня был найден, замечательно, в Руководстве разработчика Bugzilla: «Если вы пытаетесь быть умным вместо того, чтобы пытаться быть читабельным, то, возможно, вы пытаетесь сделать вещи« быстрее »?» Если так, просто запомните : не решайте проблему, пока не узнаете, что она существует. Если вы не знаете (по фактическим подробным тестам), что ваш код медленный, не беспокойтесь о том, чтобы сделать его «быстрее». Это не ограничивается оптимизация - многие программисты постоянно решают проблемы, с которыми никто никогда не сталкивался. Не делайте этого ». bugzilla.org/docs/developer.html#general
Марко

7
Я в целом согласен - за исключением одной строки, я утверждаю, что "каждый идиот думает, что он может микрооптимизировать" ...;)
Nim

@Nim: Точка занята;)
back2dos

26

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

Я согласен с большинством других комментариев - то, что раньше делало программы на C быстрее, может не делать этого сегодня - но есть и другие серьезные вещи, которые следует учитывать: я должен использовать C или C ++? Классы с простыми перегруженными операторами могут снизить производительность, если вы будете их часто использовать. Это имеет значение? Это зависит от вашего приложения, но если вы даже не учитываете его, вы не очень хороший программист. Некоторые люди могут рассмотреть это в течение приблизительно 2 миллисекунд и отклонить это, но я думаю, что слишком многие буквально даже не учитывают это.

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

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

Например, скажем, вы написали что-то вроде Angry Birds на ПК или для игровой приставки. Вы пренебрегали оптимизацией в своей физической системе и в вашей графической системе - потому что в наши дни двухъядерные процессоры с тактовой частотой 2,5 ГГц - это минимум, и ваша игра работает достаточно хорошо. Затем появляются смартфоны, и вы хотите их портировать. Черт возьми, ядро ARM 600 МГц ?

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

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

Это не популярное мнение на этих сайтах. До свидания пока очки репутации ....


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

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

@Caleb: пример Angry Birds иллюстрирует, почему бы не оптимизировать под конкретное оборудование. Он также иллюстрирует, как вы можете создать целое приложение, не потрудившись выполнить более общие оптимизации на уровне C, а затем сгореть. На самом деле не сгорел, но с трудом выходит за рамки вашего первоначального намерения.
phkahler

25

Давайте сначала возьмем ваше дело: PHP

  • Я не думаю, что PHP является своего рода языком (как по своей природе, так и по основной области применения), что вам нужно беспокоиться об этих «микрооптимизациях». PHP-код в основном оптимизирован с помощью кэширования кода операции.
  • Программы, написанные на PHP, не связаны с процессором, в основном они связаны с вводом / выводом , поэтому в любом случае эти оптимизации не будут стоить вашего времени.
  • Все, что вы ДОЛЖНЫ оптимизировать, должно быть добавлено в расширение C, а затем динамически загружено во время выполнения PHP.
  • Таким образом, как вы можете видеть, у нас нет стимула для микрооптимизации нашего кода на PHP - с другой стороны, если вы потратите это время на то, чтобы сделать код PHP более читабельным и обслуживаемым, - это принесет вам больше дивидендов.

В общем,

Я бы не стал тратить «TOOOOO» на оптимизацию своего кода на динамическом языке, таком как Python или Ruby, потому что они НЕ предназначены для задач, требующих значительных вычислительных ресурсов . Они решают различные проблемы, где моделирование реальной ситуации сложным образом (которое легко читать и поддерживать) - что называется экспрессивностью - важнее скорости. Если бы скорость была главной заботой, они бы не были динамичными.

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

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

  • Что вы делаете: домен приложения, сложность?
  • Действительно ли улучшения в микросекундах ДЕЙСТВИТЕЛЬНО важны для вашей программы?
  • Какой вид оптимизации будет наиболее прибыльным? Это может быть не всегда оптимизация кода, а нечто внешнее.
  • Сколько «блага» (с точки зрения скорости) вы пожинаете за время, потраченное на микрооптимизацию?
  • Можно ли достичь более высоких скоростей другими способами - путем изменения аппаратного обеспечения, ОЗУ и процессора, параллельного выполнения кода или в распределенной системе?

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


18

Кажется, есть много ответов, в которых говорится, что

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

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

if (counter < X && shouldDoThis()) // shouldDoThis() is an expensive function

всегда лучше, чем

if (shouldDoThis() && counter < X ) 

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

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


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

4
Это очень опасный пример. Оптимизация не должна никогда изменить поведение . Даже предположение, что cheap() && expensive()это оптимизация, expensive () && cheap()предлагает людям слепо заменять одно другим без учета значительных семантических изменений, которые оно создает (в языках, где &&оператор короткого замыкания).
Марк Бут

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

3
@MarkBooth Я должен согласиться с phkahler, ни одна из этих функций не должна иметь побочных эффектов! Порядок использования condionos в операторе if не должен влиять на результат программы. Мой пример был бы лучше написан как if (x<100 && isPrime(x)), просто чтобы сделать его более понятным.
zidarsk8

1
@ zidarsk8 - Если оптимизация изменяет что-либо кроме скорости выполнения, то это не оптимизация . Как программисты мы часто должны быть прагматичными , и иногда это означает, что мы не можем гарантировать, что все функции, используемые с оператором короткого замыкания, являются чистыми - особенно когда наш код вызывает сторонние библиотеки, над которыми мы не имеем никакого контроля. В этой ситуации вы должны быть осторожны, чтобы неопытным программистам не предлагалось вводить ошибки во имя оптимизации .
Марк Бут

11

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

«Лучшая практика» - лучший выбор с учетом всех обстоятельств. Например, вместо встроенного SQL следует использовать LINQ и Entity Framework . В моей компании мы находимся на SQL Server 2000 . SQL Server 2000 не поддерживает Entity Framework. Лучшие практики требуют:

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

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

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

« Для всего есть время, время для любой деятельности под небесами ».


1
Кстати, вы можете использовать Dapper в качестве альтернативы микро-ORM для встроенного SQL.
Дан

2
LINQ and Entity Framework should be used in lieu of inline SQL- до тех пор, пока вам не понадобится встроенный SQL для оптимизации чего-либо; SQL, который генерирует EF, не всегда оптимален.
Роберт Харви

1
FWIW, если ваш босс беспокоит стоимость лицензионного SQL 2k8 (или что - то еще может быть ток), следует отметить, что это достаточно старо , чтобы быть приходить-на EOL очень скоро (если это не уже)
заповедное

@ Warren - Некоторые компании не принимают такие вещи во внимание. Для некоторых, если это все еще «работает», они не будут обновляться. Под работой я подразумеваю, что сервер все еще работает. Мы уже видим отсутствие поддержки с EF. Этого просто недостаточно, чтобы убедить их потратить деньги.
P.Brian.Mackey

1
Как вы знаете, вы можете использовать EF с SQL 2000. Конструктор не работает, но фактическая структура сущностей поддерживает SQL 2000. Чтобы обойти ограничение конструктора, вы можете создать локальную базу данных в SQL Express в той же схеме в качестве базы данных sql 2000, укажите на конструктор, чтобы он сгенерировал все классы, затем перейдите в файл .edmx и измените целевую версию базы данных на 2000 и укажите строку подключения в своей базе данных sql server 2000. Не лучшее решение, но если вы не можете обновить его, оно работает.
Нил

8

Это всегда компромисс.

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

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

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

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

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

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

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

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


«Всегда есть компромисс». Правда, уменьшение одной переменной увеличит другую, если программа находится на кривой компромисса . По моему опыту, большинство программ далеко не соответствуют кривой компромисса, и в них достаточно места для уменьшения обеих переменных.
Майк Данлавей

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

@Boz kay> Это частично правда. Во-первых, потому что ваш начальник и обычные люди в основном ничего не знают о суммах и не заботятся о деньгах. Если вы хотите продвигать некоторые инструменты с открытым исходным кодом, вы должны рассказать им, как это улучшит бренд компании или как это сократит затраты на развитие. Кроме того, радость разработчиков - это способ получить хорошего разработчика в вашей компании. Хороший разработчик зарабатывает деньги (в основном бросает качество и инновации). В конце концов, деньги - это ключ. И я пишу это с моего компьютера Linux, который является отличным сторонником свободного программного обеспечения. То же самое касается образования.
Deadalnix

8

Производительность это особенность

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

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

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


7

Время разработчика стоит больше, чем время компьютера. Обычно это то, что вы хотите оптимизировать. Но:

  • Есть разница между микрооптимизацией и алгоритмической сложностью. Потратьте достаточно времени, чтобы убедиться, что вы используете правильный алгоритм .
  • Убедитесь, что вы задаете правильный вопрос, select (select count(*) from foo) >= 1это не то же самое, что select exists(select 1 from foo).
  • некоторые языковые идиомы популярны просто потому, что они быстрее, их можно использовать, так как большинство беглых пользователей языка будут с ними знакомы. (ваш пример хороший пример).

7

Что вы хотите оптимизировать?

  • Производительность программного обеспечения?
  • Надежность?
  • Производительность программиста?
  • Удовлетворенность клиентов?
  • Энергоэффективность?
  • Ремонтопригодность?
  • Пора торговать?
  • Стоимость?

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

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

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

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


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

+1 очень нравится ваш список возможных оптимизаций. Он использовал сборку / фортран
Boz

@Styler: скоро у мобильных устройств будет четырехъядерный процессор с гигабайтами памяти, у нас уже есть двухъядерные смартфоны.
Ли Райан

@Lie Райан: да, это правда, но, как и большинству пионеров, им приходилось путешествовать на деревянных лодках;)
Styler

7

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

ОДНАКО программист должен стараться избегать глупостей во время написания кода.

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

Опытные программисты легко запоминают эти вещи и почти всегда улучшают качество кода.


Поняв, что мне нужно быть более ясным в редактировании моего вопроса, я действительно говорил то же самое - я обновил его.
Boz

7

Решая, что оптимизировать, всегда помните закон Амдала . Смотрите ссылку для точной математики; содержательное утверждение, которое нужно запомнить:

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

Вот почему люди всегда говорят, что не стоит оптимизировать те части вашей программы, которые занимают не более нескольких процентов от общего времени выполнения. Но это всего лишь частный случай более общего принципа. Закон Амдаля гласит, что если вам нужно, чтобы вся программа работала вдвое быстрее, вам нужно ускорить каждую часть в среднем на 50%. Он говорит вам, что если вам нужно обработать двадцать гигабайт данных, есть только два способа сделать это быстрее, чем время, необходимое для считывания двадцати гигабайт с диска: получить более быстрый диск или уменьшить объем данных.

Так что же говорит закон Амдаля о микрооптимизациях? Это говорит о том, что они, возможно, того стоят, если они подадут заявку через доску. Если вы можете сэкономить один процент времени выполнения каждой функции в вашей программе, поздравляем! Вы ускорили программу на один процент. Стоило ли это делать? Ну, как парень компилятор, я был бы рад найти оптимизацию, которая сделала бы это, но если вы делаете это вручную, я бы сказал, искать что-то большее.


1
+1 за цитату Амдала, но я не согласен с тем, что «чтобы вся программа работала вдвое быстрее, вам нужно ускорить каждую часть». Я бы сказал, что вы на самом деле не ускоряете «кусочек». Скорее вы найдете ненужную работу и устраните ее. Особенно вызовы функций, если программа - нечто большее, чем игрушка. Большая часть общего представления о производительности, похоже, полностью игнорирует важность поиска целых ненужных ветвей дерева вызовов (которые могут быть отдельными инструкциями) и их отключения.
Майк Данлавей

Дьявола в слове "средний" нет. Математически случай, когда для ускорения программы на 50% каждая часть должна быть ускорена в среднем на 50% . Теперь, если вы можете разделить программу на работу, которая занимает 75% времени выполнения, и другую, которая занимает 25%, и ускорить предыдущую в 3 раза, это даст вам 50% в целом, несмотря на то, что вы ничего не сделали для последней работы. Но гораздо более распространенным случаем является то, что существуют десятки «заданий», каждое из которых занимает менее 5% времени выполнения, а затем вам нужно ускорить или избавиться от многих из них.
Звол

Я думаю, что есть еще более распространенный случай. «Работа» занимает 50% времени, но на самом деле она вам не нужна , поэтому вы полностью ее удаляете, сокращая общее время на эту величину, а затем повторяете. Я знаю, что это трудно принять - программы могут тратить большие доли времени на то, что (задним числом) совершенно не нужно. Но вот мой канонический пример .
Майк Данлавей

6

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

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

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

  • Код хорошо написан?
  • Может ли приложение получить доступ к своим данным без проблем?
  • Можно ли использовать лучший алгоритм?

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


5

Скорость выполнения - один из многих факторов, влияющих на качество программы. Часто скорость имеет обратную корреляцию с удобочитаемостью / ремонтопригодностью. Почти во всех случаях код должен быть удобочитаемым, чтобы его можно было поддерживать. Единственный раз, когда читаемость может быть нарушена, это когда скорость является существенным требованием. Требование сделать код быстрее, чем позволяет полная читаемость / сопровождение, вряд ли когда-либо применимо, но есть определенные случаи, когда оно будет. Главное, что нужно помнить, это то, что микрооптимизированный код часто является хакерским кодом, поэтому, если где-то не существует определенного требования, это почти всегда неправильный способ решения проблемы. Например, пользователь почти никогда не заметит разницу между временем выполнения 0,5 секунды и 1 секунду в операциях CRUD, так что вам не нужно идти на сборку-interop-hackfest, чтобы добраться до этих 0,5 секунд. Да, я мог бы летать на вертолете на работу, и это было бы в 10 раз быстрее, но я не из-за цены и того, что вертолет летать намного сложнее.Когда вы без необходимости микрооптимизируете код, это именно то, что вы делаете: добавляете ненужную сложность и стоимость для достижения лишней цели.


5

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

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

Обратите внимание, что небольшие «встраиваемые» системы сегодня могут быть довольно близки к Vaxen или PDP-11 прошлого года, поэтому раньше эти проблемы были более распространенными. В современной системе общего назначения, выполняющей современные общие коммерческие вычисления, микрооптимизация встречается редко. Вероятно, это часть того, почему твой отец занимает ту же должность, которую занимает.

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

Это пример из недавнего вопроса, на который я ответил на Stack Overflow для случая, когда была необходима микрооптимизация: видеокодеры с открытым исходным кодом для встроенной системы .


4

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

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

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

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

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


4

Если вы начинаете беспокоиться о миллисекундах, вам следует отказаться от PHP и использовать вместо этого C или Assembly. Не то чтобы я хотел этого делать, просто нет смысла обсуждать такие цифры и использовать язык сценариев. Ваш код повторяется с этой командой, что часто так или иначе?

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

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


+1 выключить свет или не отвечать на вопросы.
Boz

4

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

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


BubbleSort на самом деле может быть лучше, чем быстрая сортировка или сортировка слиянием, когда ваши данные почти отсортированы с использованием всего лишь нескольких случайных элементов, которые находятся не слишком далеко от конечного пункта назначения. Однако для всех других задач вы должны использовать встроенную функцию сортировки, которую обеспечивает ваш язык программирования; это самый простой способ начать работу (а встроенная функция сортировки в большинстве языков имеет хорошую производительность). ПЛОХОЙ СОВЕТ: start out with bad runtime characteristicне умышленно начинать с плохой характеристики времени выполнения.
Ли Райан

@ Ли, если вы ЗНАЕТЕ, что ваши данные почти отсортированы, и ПОЭТОМУ вы можете использовать пузырьковую сортировку, вы не совсем слепо выбираете свой алгоритм ... Также спасибо за указание на опечатку.

4

Я говорил это раньше, и я скажу это здесь: «Преждевременная оптимизация - корень всего зла» . Это должно быть одним из правил в центре внимания любого программиста.

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

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

Есть некоторые вещи, которые вы должны решить заранее, что повлияет на производительность; очень простые решения, такие как язык / время выполнения, которые вы будете использовать для реализации этого решения. Многие из них будут влиять на производительность на много порядков больше, чем вызов одного метода против другого. Честно говоря, PHP как язык сценариев уже является ударом по производительности, но так как очень мало сайтов со сценариями создаются снизу вверх в C / C ++, он сопоставим с другими технологиями, которые вы, вероятно, выберете (Java Servlets, ASP.NET). , и т.д).

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


2
+1 Создание кода, который работает, должен ВСЕГДА быть первым приоритетом.
Boz

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

«Заставь это работать, а затем заставь работать так же быстро, как и нужно», Анон.
Джон Сондерс

1
На самом деле религия - корень всего зла, но я отвлекся.
Томас Эдинг

4

Вы упоминаете, что ваш папа - бывший программист. Программисты, работавшие в мире мэйнфреймов, должны были быть очень обеспокоены производительностью. Я помню, как изучал деятельность ВМФ США, где их мэйнфрейм был аппаратно ограничен до 64 КБ памяти на пользователя. В этом мире программирования вы должны делать все возможное.

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


3

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


3

Это важно, если:

1) Чья-то жизнь зависит от вашего кода. Функция, выполняемая в чьем-то пульсометре за 25 мс, вероятно, плохая идея.

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


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

3

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

Нет, учитывая, что существуют платформы, такие как JVM и .NET, где код написан для виртуальной машины, и поэтому попытка оптимизировать выполнение может не сработать, а то, что оптимально для рабочего стола разработчика, не обязательно будет одинаковым на сервере. Посмотрите, как далеко от оборудования некоторые из этих высокоуровневых программ находятся для другого момента здесь. Что-то нужно учитывать, учитывая разнообразие оборудования, насколько реалистично оптимизировать код для конкретных чипов, таких как ЦП или ГП, когда новая модель, вероятно, выйдет менее чем через год?

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


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


1
Обратите внимание, что вы можете проводить микрооптимизацию на платформах, таких как JVM и .NET, они просто принимают несколько разные формы. Но то же самое верно, если сравнивать старый и простой C-компилятор с более современным, высокооптимизируемым компилятором: оптимизации, которые может выполнять пользователь, будут выглядеть иначе.
Иоахим Зауэр

1

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

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

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

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

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


1

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

Статья о бессмысленных микрооптимизациях :

Как и большинство из нас, я устал читать сообщения в блоге о бессмысленных микрооптимизациях, таких как замена печати на echo, ++ $ i на $ i ++ или двойные кавычки на одинарные кавычки. Почему? Потому что 99,999999% времени это неактуально. Почему? Поскольку в 99,99% случаев вам лучше установить PHP-ускоритель, такой как APC, или добавить эти недостающие индексы в столбцы базы данных, или попытаться избежать тех 1000 запросов к базе данных, которые есть у вас на домашней странице.

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

Я попробовал на свежую установку WordPress. Сценарий останавливается до того, как он заканчивается «Ошибка шины» на моем ноутбуке, но количество кодов операций уже превысило 2,3 миллиона. Достаточно сказано.

Таким образом, в большинстве случаев микрооптимизация экономит 1 операцию среди миллионов, но ухудшает читаемость.


1

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

Я объясню. Плохая оптимизация (чтение преждевременно / микрооптимизация) - это не то, когда вы оптимизируете разделы кода без профилирования, чтобы узнать, действительно ли они являются узкими местами. Это когда вы оптимизируете на основе ваших предположений, слухов и недокументированного поведения. Если это задокументировано и делает что-то более эффективным / логичным способом, каким бы маленьким оно ни было, я называю это хорошей оптимизацией . Как утверждают другие, у обоих из них есть свои минусы и почти нет плюсов в том, что касается зарабатывания хорошего бизнеса, но все же я делаю последнее, а не первое, если это не полностью нарушает читабельность. Да, удобочитаемость / ремонтопригодность имеют первостепенное значение, и именно там вы проводите черту

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

  1. Ваши зависимости от конкретной проблемы могут измениться, и любое время, потраченное на оптимизацию до завершения логического раздела вашего приложения, является пустой тратой времени. Я имею в виду оптимизацию на относительно ранней стадии. Сегодня у вас есть List<T>и к тому времени, когда ваше приложение поставляется, вы должны были изменить его, LinkedList<T>и теперь весь сравнительный анализ был пустой тратой времени и усилий.

  2. В большинстве случаев реальное узкое место вашего приложения (читаемое как измеримая разница) может составлять 5% вашего кода (в основном, sql), а оптимизация остальных 95% не дает вашим клиентам никакой выгоды.

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

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

Недостатки плохой оптимизации, в частности:

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

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

Я приведу несколько примеров плохой и хорошей оптимизации:

Плохо -

  1. использование меньших целочисленных типов вместо Int32.

  2. ++i используется вместо i++

  3. forвместо foreach(худшее, что я видел, полностью побеждает логику)

  4. избегая закрытых переменных

    string p;
    foreach (var item in collection)
        p = ...;
    
  5. использование charвместо строки во время конкатенации строк, например:

    string me = 'i' + "me myself"; // something along that line - causes boxing
    

Добро (из мира .NET. Должно быть самоочевидным) -

  1. Двойной поиск

    if (Dictionary<K, V>.TryGetValue(K, out V))
        do something with V
    

    вместо

    if (Dictionary<K, V>.ContainsKey(K))
        do something with Dictionary<K, V>[K]
    
  2. Загрузить все

    DirectoryInfo.EnumerateFiles();
    

    вместо

    DirectoryInfo.GetFiles();
    
  3. Двухступенчатый кастинг:

    s = o as string;
    if (s != null)
        proceed
    

    вместо

    if (o is string)
        s = (string)o;
    
  4. Если заказ не имеет значения

    if (counter < X || expensiveFunction())
    

    вместо

    if (expensiveFunction() || counter < X)
    
  5. Заниматься боксом

    void M<T>(T o) //avoids boxing
    {
    
    }
    

    вместо

    void M(object o)
    {
    
    }
    

Если вы спросите меня, дают ли они заметные преимущества в производительности, я бы сказал нет. Но я бы предложил использовать их, потому что это вытекает из понимания поведения этих конструкций. Зачем делать два звонка, когда вы можете сделать только 1? С философской точки зрения это хорошая практика кодирования. И 1 и 3 немного менее читабельны в строгом смысле слова, но имеют ли они преимущество перед читаемостью? Нет, не так много, поэтому я использую. Теперь это ключ - поддержание достойного соотношения производительности и читабельности. И когда это так, то где вы проводите черту.


1

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

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

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

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

Не так давно мне удалось сократить время работы с 24 секунд до 25 миллисекунд (примерно в 960 раз быстрее), с одинаковыми выходами (защищенными автоматизированными тестами), без изменений в алгоритмической сложности, для объемного рассеяния тепла, посредством «микрооптимизации» (самая большая из которых произошла из-за изменения в структуре памяти, которое сократилось примерно до 2 секунд, затем остальными были такие вещи, как SIMD и дальнейший анализ ошибок кеша в VTune и некоторая дальнейшая перестройка структуры памяти).

Вольфир объясняет здесь технику, и он боролся со временем, необходимым: http://blog.wolfire.com/2009/11/volumetric-heat-diffusion-skinning/

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

После того, как я «микрооптимизировал» его с 24 секунд до 25 мс, это стало поворотным моментом в рабочем процессе. Теперь художники могут менять свои установки в режиме реального времени со скоростью более 30 кадров в секунду, не дожидаясь 24 секунд каждый раз, когда они вносят небольшие изменения в свою установку. И это на самом деле изменило весь дизайн моего программного обеспечения, так как мне больше не нужны индикатор выполнения и все в этом роде, просто все стало интерактивным. Так что это может быть «микрооптимизация» в том смысле, что все улучшения произошли без какого-либо улучшения алгоритмической сложности, но это была скорее «мегаоптимизация», которая сделала то, что раньше было болезненным, неинтерактивным процессом в режиме реального времени, интерактивный, который полностью изменил способ работы пользователей.

Измерение, пользовательские требования, контекст

Мне очень понравился комментарий Роберта, и, возможно, я не смог сделать то, что хотел:

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

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

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

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


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

1
@RobertHarvey Это было своего рода замечание, которое я надеялся сделать, поскольку то, что некоторые люди называют «микрооптимизацией», не обязательно является микроскопическим, но оно настолько зависит от контекста, измерений и т. Д., По issetсравнению с strlenболее мелким фокусом отсутствует контекст и измерения. :-D
Энергия Дракона

1
@RobertHarvey Я надеялся сказать, может быть, хотя и косвенно, что если есть «негативный контекст» для «микрооптимизаций», то это тип, который, как правило, лишен этих измерений, контекстов и потребностей конечного пользователя. Я мог бы продолжить и последний случай, так как у меня был коллега, который оптимизировал чертовски что-то классное, за исключением того, что никто не использовал его. Я даже думаю, что правильная оптимизация требует некоторого понимания со стороны пользователя, иначе мы могли бы профилировать и настраивать вещи, которые не интересуют пользователей.
Энергия Дракона,

1
Некоторые оптимизации обусловлены насущной необходимостью, а другие - любопытством (интеллектуальное преследование и авантюризм). Нам нужны оба. В истории Dragon Energy это, вероятно, не было «насущной необходимостью», поскольку художники, по-видимому, не жаловались громко на то, что не видят результатов рендеринга в течение 24 секунд после каждого редактирования. На самом деле, пользователи могут не знать, как быстро это могло бы быть, пока программист не приложит все усилия, чтобы побить рекорд скорости. Ограничение себя управляемым спросом имеет смысл для бизнеса, но при этом упустятся некоторые потрясающие возможности оптимизации или изменения в игре.
Руонг

1
Говоря о деловом смысле, существует также проблема монетизации. Каждый шаг (например, программист, работающий над оптимизацией производительности) стоит денег, и затраты должны быть окуплены, чтобы иметь смысл в бизнесе. Таким образом, нужно спросить, можно ли «продать» улучшение скорости, изменяющее игру, или сколько денег будет «сэкономлено», если программист должен получить одобрение от бизнес-менеджера.
Руонг

0

Я бы сказал так: микрооптимизация - это процесс оптимизации чего-то, что не является узким местом вообще. Например, если ваша программа вызывает две функции A и B, и для завершения A требуется 100 миллисекунд, а для B - 2 микросекунды, и вы продолжаете оптимизировать функцию B. Это не только не важно, но и совершенно неправильно. Но функция оптимизации B называется оптимизацией, а не микрооптимизацией. Важность оптимизации зависит. Скажем, вам больше нечего делать, и ваша программа не содержит ошибок, тогда да, это важно. Но, как правило, у вас есть приоритеты. Допустим, вам нужно добавить / записать функцию C. Если вы думаете, что написание функции C принесет вам больше денег, чем ускорение вашей программы без этой функциональности, тогда переходите к оптимизации. В противном случае преследовать функциональность. Также, опытные программисты, ориентированные на производительность, не тратят много времени на оптимизацию, они просто пишут быстрые программы. По крайней мере, они знают, какие инструменты использовать и что делать, чтобы не тратить годы на бессмысленную (читай микро) оптимизацию.


этот пост довольно трудно читать (стена текста). Не могли бы вы изменить его в лучшую форму?
комнат
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.