«Преждевременная оптимизация - корень всего зла» - это то, что почти все мы слышали / читали. Что мне интересно, какая оптимизация не является преждевременной, то есть на каждом этапе разработки программного обеспечения (дизайн высокого уровня, детальный дизайн, реализация высокого уровня, детальная реализация и т. Д.), Какую степень оптимизации мы можем рассмотреть, не переходя на темную сторону.
optimization
Gaurav
источник
источник
Ответы:
Когда вы основываете это на опыте? Не зло «Каждый раз, когда мы делали X, мы терпели жестокий удар по производительности. Давайте на этот раз планируем либо оптимизировать, либо полностью избегать X».
Когда это относительно безболезненно? Не зло «Реализация этого как Foo или Bar займет столько же работы, но теоретически Bar должен быть намного более эффективным. Давайте Bar это».
Когда вы избегаете паршивых алгоритмов, которые будут ужасно масштабироваться? Не зло «Наш технический руководитель говорит, что предлагаемый нами алгоритм выбора пути работает в факториальное время; я не уверен, что это значит, но она предлагает, чтобы мы взяли на себя seppuku, чтобы даже рассмотреть его. Давайте рассмотрим кое-что еще».
Зло происходит из-за того, что ты тратишь много времени и энергии на решение проблем, о которых ты даже не подозреваешь. Когда проблемы определенно существуют или когда призрачные псевдо-проблемы могут быть решены дешево, зло исчезает.
Steve314 и Matthieu M. поднимают вопросы в комментариях, которые следует рассмотреть. По сути, некоторые разновидности «безболезненных» оптимизаций просто не стоят того, потому что предлагаемое ими тривиальное обновление производительности не стоит запутывания кода, они дублируют улучшения, которые уже выполняет компилятор, или и то, и другое. Посмотрите комментарии для некоторых хороших примеров слишком хитрых половинных улучшений.
источник
i
не подписано,i / 2
может быть заменено наi >> 1
. Это быстрее. Но это также более загадочно (не все увидят эффект, даже те, кто это делает, могут потерять время). Но хуже всего то, что компилятор все равно это сделает, так зачем запутывать исходный код;)?i/2
действительно является горячей точкой и что (невероятно, но давайте предположим)i>>1
делает это быстрее, то сделайте это и добавьте комментарий, чтобы это профилирование показало, что это быстрее. Если это действительно нужно где-то (что я сомневаюсь, так как, как сказал Матье, компиляторы должны быть достаточно умными, чтобы сделать это сами), новички узнают что-то, если это не так (что вероятно), почему вы хотите подключить их головы с ненужным фольклором?Код приложения должен быть настолько хорошим, насколько это необходимо, но код библиотеки должен быть настолько хорошим, насколько это возможно, поскольку вы никогда не знаете, как будет использоваться ваша библиотека. Поэтому, когда вы пишете библиотечный код, он должен быть хорош во всех аспектах, будь то производительность, надежность или любая другая категория.
Кроме того, вам нужно думать о производительности при разработке приложения и при выборе алгоритмов . Если он не предназначен для повышения производительности, никакая степень хакерства не сможет впоследствии сделать его эффективным, и никакие микрооптимизации не перевесят превосходный алгоритм.
источник
Вид, который приходит в результате известных проблем.
источник
Трудно сказать, что такое добро и зло. У кого есть это право? Если мы посмотрим на природу, кажется, что мы запрограммированы на выживание с широким определением «выживания», которое включает передачу наших генов потомству.
Так что я бы сказал, по крайней мере, в соответствии с нашими основными функциями и программированием, что оптимизация не является злом, когда она согласуется с целью воспроизведения. Для парней есть блондинки, брюнетки, рыжие, многие милые. Для девушек есть парни, и некоторые из них кажутся нормальными.
Возможно, мы должны оптимизировать для этой цели, и там это помогает использовать профилировщик. Профилировщик позволит вам расставить приоритеты и оптимизировать время, а также предоставит вам подробную информацию о горячих точках и причинах их возникновения. Это даст вам больше свободного времени, потраченного на репродукцию и ее преследование.
источник
Полная цитата определяет , когда оптимизация не преждевременно:
Вы можете идентифицировать критический код разными способами: критические структуры данных или алгоритмы (например, интенсивно используемые или «ядро» проекта) могут дать существенные оптимизации, многие незначительные оптимизации идентифицируются с помощью профилировщиков и так далее.
источник
Вы должны всегда выбирать «достаточно хорошее» решение во всех случаях, основываясь на вашем опыте.
Под оптимизацией понимается написание «более сложного кода, чем« достаточно хорошего », чтобы сделать его быстрее», перед тем, как на самом деле понять, что это необходимо, и, следовательно, сделать код более сложным, чем необходимо ». Сложность - это то, что делает вещи трудными, так что это не очень хорошая вещь.
Это означает, что вам не следует выбирать суперкомплекс «сортировать файлы по 100 ГБ путем прозрачной загрузки на диск», когда будет выполнять простую сортировку, но вы также должны сначала сделать хороший выбор для простой сортировки. Слепой выбор Bubble Sort или «выбрать все записи случайным образом и посмотреть, в порядке ли они. Повторите.» редко бывает хорошим
источник
Мое общее правило: если вы не уверены, что вам понадобится оптимизация, предположите, что это не так. Но имейте это в виду, когда вам нужно оптимизировать. Есть некоторые проблемы, о которых вы можете знать заранее. Обычно это включает выбор хороших алгоритмов и структур данных. Например, если вам нужно проверить членство в коллекции, вы можете быть уверены, что вам понадобится некоторый тип структуры данных набора.
источник
По моему опыту, на этапе детальной реализации ответ заключается в профилировании кода. Важно знать, что должно быть быстрее, а что приемлемо быстро.
Также важно знать, где именно узкое место в производительности - оптимизация части кода, которая занимает всего 5% от общего времени выполнения, не принесет пользы.
Шаги 2 и 3 описывают преждевременную оптимизацию:
источник
Это не оптимизация при выборе вещей, которые трудно изменить, например: аппаратная платформа.
Выбор структуры данных является хорошим примером - критически важным для удовлетворения как функциональных, так и нефункциональных требований (производительности). Не легко изменить, и все же он будет управлять всем остальным в вашем приложении. Ваши структуры данных меняют доступные алгоритмы и т. Д.
источник
Я знаю только один способ ответить на этот вопрос - получить опыт в настройке производительности. Это значит - писать программы, и после того, как они будут написаны, найти ускорения в них, и делать это итеративно. Вот один пример.
Вот ошибка, которую совершают большинство людей: они пытаются оптимизировать программу перед тем, как ее запустить. Если они прошли курс программирования (у профессора, который на самом деле не имеет большого практического опыта), у них будут большие цветные очки, и они подумают, что это все . Это все та же проблема, предварительная оптимизация. **
Кто-то сказал: сначала сделай это правильно, а потом сделай это быстро. Они были правы.
Но теперь для кикера: если вы сделали это несколько раз, вы узнаете глупые вещи, которые вы делали ранее, которые вызывают проблемы со скоростью, поэтому вы инстинктивно избегаете их. (Такие вещи, как создание слишком тяжелой структуры вашего класса, заваление уведомлениями, смешение размера вызовов функций с их стоимостью времени, список можно продолжать и продолжать ...) Вы инстинктивно избегаете этого, но догадаетесь, как это выглядит для менее опытный: преждевременная оптимизация!
Так что эти глупые дебаты продолжаются и продолжаются :)
** Еще одна вещь, которую они говорят, это то, что вам больше не нужно об этом беспокоиться, потому что компиляторы такие хорошие, а машины такие быстрые в наше время. (KIWI - Kill It With Iron.) Не существует экспоненциального аппаратного или системного ускорения (выполненного очень умными трудолюбивыми инженерами), которое могло бы компенсировать экспоненциальное замедление программного обеспечения (созданное программистами, которые так думают).
источник
Когда требования или рынок специально просит об этом.
Например, производительность является требованием в большинстве финансовых приложений, потому что низкая задержка имеет решающее значение. В зависимости от характера торгуемого инструмента, оптимизация может перейти от использования неблокирующих алгоритмов на языке высокого уровня к использованию низкоуровневого языка и даже самого крайнего - реализации алгоритмов согласования порядка в самом аппаратном обеспечении (например, с использованием FPGA). ).
Другим примером могут быть некоторые типы встроенных устройств. Взять, к примеру, тормоз ABS; Во-первых, существует безопасность, когда вы попадаете в перерыв, машина должна замедляться. Но есть и производительность, вы не хотели бы никаких задержек, когда вы выходите на перерыв.
источник
Большинство людей назвали бы оптимизацию преждевременной, если вы оптимизируете что-то, что не приводит к «мягкому отказу» (это работает, но все еще бесполезно) системы из-за производительности.
Примеры из реального мира.
Если для выполнения моей сортировки пузырьков требуется 20 мс, оптимизация до быстрой сортировки 1 мс не приведет к значительному повышению общей полезности, несмотря на увеличение производительности на 2000%.
Если загрузка веб-страницы занимает 20 секунд, а мы уменьшаем ее до 1 секунды, это может увеличить полезность веб-сайта с 0 до бесконечности. В основном то, что было сломано, потому что это было слишком медленно, теперь полезно.
источник
Какой вид оптимизации не является преждевременным?
Оптимизация, которая устраняет известную проблему производительности вашего приложения, или оптимизация, которая позволяет вашему приложению соответствовать четко определенным критериям приемлемости.
После определения необходимо потратить некоторое время, чтобы установить исправление и измерить выигрыш в производительности.
(то есть это не так - «Я думаю, что этот фрагмент кода выглядит медленным, я заменю X на Y вместо этого, и это будет быстрее»).
Я столкнулся с множеством преждевременных «оптимизаций», которые в конечном итоге сделали код медленнее - в данном случае я считаю преждевременным значение «не продумано». Производительность должна оцениваться до и после оптимизации, и должен сохраняться только тот код, который действительно улучшает производительность.
источник
Правда. К сожалению, это также одна из самых (злонамеренно) неправильно используемых программных цитат всех времен. Поскольку Дональд Кнут создал мем, стоит добавить оригинальный контекст из цитаты:
Обратите внимание, что Кнут говорил конкретно о скорости выполнения во время выполнения .
Кроме того, он написал эту статью в 1974 году, когда любые ресурсы машины, в которых премиальная и отрицательная корреляция между скоростью выполнения и ремонтопригодностью программы (более высокая скорость - менее ремонтопригодна), вероятно, были сильнее, чем сейчас.
Хорошо, чтобы ответить на ваш вопрос, согласно Дональду Кнуту, оптимизация НЕ является преждевременной, если она устраняет серьезное узкое место в производительности, которое было идентифицировано (в идеале измеряется и точно определяется во время профилирования).
Как я уже говорил ранее, «преждевременная оптимизация» является одним из наиболее злонамеренно неправильно используемых мемов, поэтому ответ не будет полным без некоторых примеров вещей, которые не являются преждевременной оптимизацией, но иногда игнорируются как таковые:
Далее даже не связаны со скоростью выполнения во время выполнения:
продуманный дизайн
статическая типизация (!)
и т.д. / любые формы умственного усилия
источник