Я программировал пару лет и часто оказывался перед дилеммой.
Есть два решения -
- один простой, то есть простой подход, легче понять и поддерживать. Это предполагает некоторую избыточность, некоторую дополнительную работу (дополнительный ввод-вывод, дополнительную обработку) и, следовательно, не является наиболее оптимальным решением.
- но другой использует сложный подход, трудный для реализации, часто включающий взаимодействие множества модулей и являющийся эффективным решением.
К какому решению я должен стремиться, когда у меня нет жесткой производительности SLA, и даже простое решение может соответствовать производительности SLA? Я чувствовал презрение среди моих коллег-разработчиков к простому решению.
Является ли хорошей практикой создание наиболее оптимального комплексного решения, если ваш SLA производительности может быть удовлетворен простым решением?
design
programming-practices
coding-style
code-quality
performance
Двигайся быстрее
источник
источник
Ответы:
Простой. Он соответствует спецификациям, его легче понять, легче поддерживать и, вероятно, он намного менее глючит.
То, что вы делаете для защиты эффективного решения, - это внесение умозрительной общности и преждевременной оптимизации в ваш код. Не делай этого! Производительность идет вразрез с практически любой другой «способностью» разработки программного обеспечения (надежность, ремонтопригодность, удобочитаемость, тестируемость, понятность, ...). Погоня за производительностью при тестировании показывает, что действительно нужно гоняться за производительностью.
Не гонитесь за производительностью, если производительность не имеет значения. Даже если это имеет значение, вы должны преследовать производительность только в тех областях, где тестирование показывает, что существует узкое место в производительности. Не допускайте, чтобы проблемы с производительностью служили поводом для замены
simple_but_slow_method_to_do_X()
более быстрой версией, если эта простая версия не является узким местом.Повышение производительности почти неизбежно связано с множеством проблем с запахом кода. Вы упомянули несколько вопросов: сложный подход, сложный для реализации, более высокая связь. Это действительно стоит потянуть?
источник
Краткий ответ: предпочитайте простые решения сложным и помните принципы KISS и YAGNI
Поскольку первоначальные требования проекта и программное обеспечение никогда не бывают идеальными, оно требует изменений по мере разработки / использования приложения. Итеративный подход на этапах разработки очень хорошо подходит для простого начала и расширения его по мере необходимости. Самые простые решения имеют пространство для гибкости и просты в обслуживании.
Кроме того, пытаться быть умным и размещать дополнительную оптимизацию, в то же время создавая приложение, не является хорошей практикой и может слишком усложнить ваше решение. Как известно,
"premature optimization is the root of all evil"
- из книги Кнутаисточник
Возьмите урок от Кнута: «Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла».
Подумайте о ваших решениях в следующем порядке: во-первых, всегда правильность. Во-вторых, улучшить ясность и простоту. В-третьих, и только тогда, когда вы можете продемонстрировать необходимость, эффективность.
Повышение эффективности почти всегда будет стоить вам чего-то важного, поэтому его следует преследовать только тогда, когда вы в этом нуждаетесь.
источник
Простота является предпосылкой надежности . Если у вас есть простое решение, которое работает, обязательно сделайте это! Оптимизировать рабочую программу намного проще, чем заставить оптимизированную программу работать. Также не забывайте о законе Мура : если ваше простое решение соответствует сегодняшним целям производительности, оно, вероятно, сокрушит их 1 раз в год или два.
1 Там нет никаких гарантий, потому что, как отметил Джимми Хоффа в своем комментарии ниже, закон Мура имеет свои пределы.
источник
Оптимальное слово неоднозначное!
В конечном счете, если существует большой риск необходимости поддерживать сложный, и если простой является «достаточно хорошим», я бы всегда ошибался на стороне простого.
Добавьте любой риск того, что сложный не достаточно хорош, тогда KISS, вероятно, является правильным ответом.
источник
Я бы предпочел простой. На мой взгляд, преждевременные оптимизации вызывают столько проблем, сколько они решают. Во многих случаях хороший дизайн позволяет вам изменять данные реализации в будущем, если они становятся узкими местами.
Итак, суть в том, что я спроектирую его максимально гибким, но не слишком пожертвую простотой ради гибкости.
источник
Какой стоит дешевле?
В большинстве случаев простое решение, которое немного медленнее, будет совершенно приемлемым с точки зрения производительности, а простота делает разработку, обслуживание и, в конечном итоге, замену более дешевой.
С другой стороны, иногда скорость действительно важна, и финансовая выгода, получаемая даже при небольшом улучшении скорости, может быть намного больше, чем увеличение стоимости более сложного решения. Например, сокращение времени на 0,01 с для завершения транзакции может сделать систему торговли ценными бумагами гораздо более прибыльной. Повышение эффективности системы, поддерживающей несколько миллионов пользователей, на 10% может означать значительное снижение затрат на сервер.
Итак, вопрос, который вы должны задать себе: имеет ли использование комплексного решения достаточное влияние на конечный результат, чтобы заплатить за его дополнительную стоимость? На самом деле, вы, вероятно, должны попросить своего клиента принять решение, так как он оплачивает счета и пожинает потенциальные выгоды. Один хороший вариант - сначала выбрать простое решение и предложить более сложное решение в качестве возможного улучшения. Это позволяет вам запустить и запустить систему и дать вашему клиенту возможность начать тестирование, и этот опыт может помочь принять решение о внедрении (или не внедрении) более сложного решения.
источник
При оценке двух подходов, один из которых проще, но менее эффективен, а другой более сложен и эффективен, необходимо учитывать проблему и предметную область проекта.
Рассмотрим многомиллиардный программный проект для отрасли здравоохранения, планируемый срок службы которого составляет более 15 лет технического обслуживания и +20 лет использования. В таком проекте производительность, безусловно, не будет проблемой, но сложность и структура проекта могут вызвать серьезные проблемы для обслуживания проекта, который длится минимум 15 лет. Ремонтопригодность и простота превыше всего.
Затем рассмотрим другой пример. Консольный игровой движок, который должен обеспечить работу будущих игр компании в течение следующих 5+ лет. Поскольку игры являются программами с чрезвычайно ограниченными ресурсами, во многих случаях эффективность превосходит удобство обслуживания. Написание ваших собственных, очень специфических структур данных и алгоритмов для какой-либо задачи может быть очень важным, даже если это идет вразрез с какими-либо «передовыми методами» разработки программного обеспечения. Хорошим примером этого может служить Data Oriented Design, в котором вы храните свои данные в похожих массивах данных, а не в реальных объектах. Это должно увеличить ссылку на локальность и, как таковой, увеличить эффективность кэша ЦП. Не практично, но очень важно в данной области.
источник
Это всегда сложный вопрос, и я вижу ответы, колеблющиеся в одну сторону, поэтому я буду играть в игру для другой стороны, хотя я не утверждаю, что любой ответ правильный, это очень мягкая и индивидуальная тема.
Одна вещь о сложном, но высокопроизводительном решении заключается в том, что вы всегда можете просто документировать его. Как правило, я фанат самодокументируемого кода, но я также фанат программного обеспечения, которое реагирует в течение определенного времени, что заставляет меня чувствовать, что это не замедляет меня. Если вы используете сложное, но высокопроизводительное решение, подумайте, что вы можете сделать, чтобы сделать его не так уж плохо:
Оберните его в интерфейс, поместите его в сборку самостоятельно, возможно, даже в процесс, который сам по себе. Сделайте его как можно более свободно соединенным с максимально толстой стенкой абстракции вокруг него, чтобы избежать утечек . Напишите множество юнит-тестов, чтобы сохранить регрессию в будущем.
Документируйте это в коде, даже подумайте о написании реальной документации. Подумайте о сложных структурах данных и о том, как они документированы, представьте, что вы пытаетесь понять реализацию одной из них из кода без книги структуры / статьи в википедии, чтобы объяснить это. И все же мы все признаем, что эти сложные структуры данных на самом деле хорошие вещи, и полезно, чтобы кто-то реализовал их на наших языках.
Помните, что мы все отправляем сообщения в стек TCP / IP, который, вероятно, такой же, какой может получить код, если кто-либо из нас захочет посмотреть на него, явно так, чтобы он выполнял так, как нам всем это тоже нужно. Возможно, ваша проблема не требует такого уровня оптимизации, возможно, это так, но будьте осторожны, когда будете решать этот вопрос, как нам всем время от времени: там будут драконы.
источник
Я иду на эту работу в областях, где нет производительности SLA. Когда речь идет о автономных средствах рендеринга в компьютерной графике, для пользователей не существует «удовлетворительной производительности», поскольку они уже выделяют огромные суммы денег для распределения вычислений по облакам и рендеринга ферм даже с помощью современных средств рендеринга. для вывода качественных изображений и кадров для фильмов, например
Но я должен сказать как один, работающий в этой области в течение многих лет, что любое решение, которое значительно ухудшает ремонтопригодность в пользу эффективности, на самом деле работает против постоянно меняющихся требований к производительности. Потому что, если вы не сможете эффективно поддерживать свое решение в течение многих лет, поскольку все меняется под вашим ногами (как с точки зрения окружающего кода, так и того, что ожидают пользователи, поскольку конкуренты продолжают превосходить друг друга), то ваше решение уже работает в направлении устаревания и необходимость оптовой замены.
Я не вижу конечной цели профилировщиков, таких как VTune, как способ заставить мой код работать быстрее. Их конечная ценность - убедиться, что я не снижаю свою производительность, чтобы соответствовать постоянно растущим требованиям к производительности. Если мне абсолютно необходимо применить какую-то грубую микрооптимизацию, то профилировщик в сочетании с выполнением его в реальных пользовательских случаях (а не в каком-то тестовом примере, который, я думаю, может оказаться важным), гарантирует, что я буду применять такой неизбежно грубый вид оптимизация очень, очень разумно, чтобы только верхние горячие точки, которые появляются, а также очень тщательно их документирование, потому что мне неизбежно придется пересматривать и поддерживать, настраивать и изменять их в течение следующих нескольких лет, если это решение останется жизнеспособным.
И особенно, если ваше оптимизированное решение требует большего количества соединений, я бы неохотно использовал его. Одним из наиболее ценных показателей, которые я оценил в наиболее критичных для производительности областях кодовой базы, является разделение (как при сведении к минимуму объема информации, которая должна работать, что также сводит к минимуму вероятность того, что она потребует изменений, если она не требует непосредственных изменений). ), потому что эти критические области значительно умножают причины для изменений. Это означает, что чем меньше информации требуется для работы, тем меньше причин для изменений и минимизация причин изменений действительно является огромной частью повышения производительности в моих конкретных сферах деятельности, потому что все равно придется постоянно меняться (мы устареет через год иначе),
Для меня самые лучшие и наиболее эффективные решения, которые я нашел, - это те, в которых эффективность, ремонтопригодность и производительность не диаметрально противоположны друг другу. Задача для меня - попытаться сделать эти концепции настолько гармоничными, насколько это возможно.
источник