Просте проти складного (але ефективне) рішення - яке вибрати та коли?


28

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

Є два рішення -

  • один простий, тобто простий підхід, легший для розуміння та підтримки. Це передбачає деяку надмірність, деяку додаткову роботу (додатковий ввід, додаткова обробка) і тому не є найбільш оптимальним рішенням.
  • але інші використовують складний підхід, складний у здійсненні, часто включає взаємодію між безліччю модулів і є ефективним рішенням.

До якого рішення слід прагнути, коли у мене немає складних угод про уможливлення, а навіть просте рішення може задовольнити ефективність угоди про рівень обслуговування? Я відчув презирство серед своїх колег-розробників щодо простого рішення.

Чи є корисною практикою розробити найоптимальніше комплексне рішення, якщо ваш рівень дозволу на обслуговування може бути задоволений простим рішенням?


10
дивіться: Як я можу уникнути "Інтуїції з поганою оптимізацією розробника"? "На жаль, розробники, як правило, мають жахливу інтуїцію щодо того, де насправді будуть проблеми з продуктивністю в додатку ...."
gnat

1
Чи буде "не найоптимальнішим" все-таки бути "досить хорошим"? Тоді залишайтеся з цим.

8
Так. " Le mieux est l'ennemi du bien. " Вольтер. ("Ідеальний - ворог добра.") Досить хороший - достатньо хороший - поки тестування продуктивності не говорить про інше.
Девід Хаммен

Я вважаю, що (загалом) просте означає ефективне. Тому часто не потрібно йти на компроміси.
День

2
"Здається, що досконалість досягається не тоді, коли більше нічого не можна додати, а коли більше нічого не можна знімати". - Антуан де Сент-Екзюпері
keuleJ

Відповіді:


58

До якого рішення слід прагнути, коли у мене немає складних угод про уможливлення, а навіть просте рішення може задовольнити ефективність угоди про рівень обслуговування?

Простий. Він відповідає специфікаціям, це легше зрозуміти, простіше в обслуговуванні, і, мабуть, набагато менше баггі.

Те, що ви робите для того, щоб відстоювати ефективне рішення ефективності, - це введення у ваш код умоглядної загальності та передчасної оптимізації. Не робіть цього! Продуктивність суперечить зерну майже будь-якої іншої інженерної інженерії програмного забезпечення, яка існує (надійність, ремонтопридатність, читабельність, тестабельність, зрозумілість, ...). Продуктивність Чейза під час тестування вказує на те, що справді потрібно гонитися за продуктивністю.

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

Підвищена продуктивність майже неминуче обтяжена проблемами запаху коду. Ви згадували декілька у запитанні: Складний підхід, важкий у здійсненні, вищий зв'язок. Це справді варто затягнути?


Ваша відповідь дуже корисна
MoveFast

1
Як можна простіше, але не простіше; Як можна швидше, але не швидше; тощо
user606723

2
"Коли ви сумніваєтеся, використовуйте грубу силу";)
tdammers

Коментарі в коді тут можуть бути як катарними, так і корисними. Невеликий коментар, що вказує на складне + швидке рішення, і чому ви його не використовували, може дати вам менше відчуття, ніби ви ігнорували оптимальний алгоритм. І це може допомогти обслуговуючим особам зрозуміти ваш вибір та направити їх у правильному напрямку, якщо оптимізація дійсно потрібна пізніше.
TheAtomicOption

12

Короткий відповідь: Віддавайте перевагу простим рішенням над складними та пам’ятайте принципи KISS та YAGNI

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

Крім того, намагання бути розумним та вносити певну додаткову оптимізацію при збереженні додатків не є хорошою практикою і може надмірно ускладнити ваше рішення. Як відомо, "premature optimization is the root of all evil"- з книги Кнут


1
@ManojGumber, жодна проблема, і це насправді суть того, про що ми, як програмісти, повинні перейматися в першу чергу.
Е.Л. Юсубов

8

Слід взяти урок з Кнут тут: "Ми повинні забути про малу ефективність, скажімо, про 97% часу: передчасна оптимізація - корінь усього зла".

Подумайте про свої рішення в такому порядку: По-перше, завжди, правильність. По-друге, підвищити чіткість та простоту. По-третє, і лише тоді, коли ви зможете продемонструвати потребу, ефективність.

Додавання ефективності майже завжди коштуватиме вам чогось важливого, і тому слід займатися лише тоді, коли знаєте, що потрібно.


4
Зауважте, що це не означає, що ви не повинні писати хорошої реалізації в першу чергу.

@ ThorbjørnRavnAndersen: звичайно, саме про це і стосуються перші два моменти.
симон

1
@simon цитата часто використовується як привід вибирати неохайно,

Про ваш другий момент: у мене був колега, який досить часто заявив, що він вважає за краще неправильно структурований та чистий код перед правильними спагетті.
Бух

@ ThorbjørnRavnAndersen некомпетентні люди використовуватимуть що-небудь для виправдання. Не впливає на значення оригінальної думки.
simon

7

Простота є необхідною умовою надійності . Якщо у вас є просте рішення, яке спрацьовує, будь-ласка, ідіть на це! Набагато простіше оптимізувати робочу програму, ніж зробити оптимізовану роботу програми. Також не забувайте про закон Мура : якщо ваше просте рішення сьогодні відповідає цілям ефективності, воно, ймовірно, розгромить їх 1 через рік-два.


1 Гарантії там немає, оскільки, як зазначив Джиммі Хоффа у своєму коментарі нижче, закон Мура має свої межі.


Ви забули про інший закон Мура, який гласив: «На жаль, про мій перший закон ...» Вибачте, бос, закон Мура вже не є (каламбур). Я не погоджуюся з рештою вашої точки зору, я б хоч би щонайменше застереження про останню частину там.
Джиммі Хоффа

2
Вибачте, але за всім моїм досвідом роботи в цій галузі. "робочі набори" збільшуються FAR швидше, ніж швидкість нашого обладнання, яке постійно удосконалюється. Дійсно, я би просто зняв точку закону Мура.
користувач606723

@ user606723 Зростання точки "робочого набору" є ортогональним для "оптимізованого чи простого" питання: навантаження на них наздожене незалежно від того, яке рішення вони реалізують. Сенс введення закону Мура в суміш полягав у тому, що навіть якщо просте рішення під час написання роботи знаходиться під деяким тиском продуктивності, тиск зменшиться, коли швидше стане доступним обладнання.
dasblinkenlight

@dasblinkenlight, зростання робочого набору є не більш ортогональним для питання, ніж закон Мура. Сенс втілення робочого набору в проблему полягає в тому, що якщо просте рішення знаходиться під деяким тиском продуктивності на момент випуску, продуктивність буде недостатньою в найближчому майбутньому, оскільки зростаючий набір знищує будь-яке підвищення продуктивності, досягнуте за рахунок покращеного обладнання. Хоча я все для простого, надійного і ремонтопрограмного забезпечення, випуск програмного забезпечення, яке вже знаходиться під тиском продуктивності при випуску, і очікую, що закон Мура навіть його вийде, - це жахлива філософія.
user606723

3

Чи є корисною практикою розробити найоптимальніше комплексне рішення, якщо ваш рівень дозволу на обслуговування може бути задоволений простим рішенням?

Оптимальне - неоднозначне слово!

Зрештою, якщо є великий ризик зберегти складний, і якщо простий є "досить хорошим", я б завжди помилявся на стороні простого.

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


2

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

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


2

Який коштує менше?

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

З іншого боку, іноді швидкість дійсно важлива, і фінансовий прибуток, який отримується від навіть невеликих покращень швидкості, може бути набагато більшим, ніж збільшення вартості більш складного рішення. Наприклад, гоління 0,01 секунди часу для завершення транзакції може зробити систему торгівлі цінними паперами набагато вигіднішою. 10% підвищення ефективності системи, яка підтримує кілька мільйонів користувачів, може означати значне зниження витрат на сервер.

Отже, питання, яке ви повинні задати собі, таке: чи має використання комплексного рішення достатньо впливу на підсумок, щоб оплатити його додаткові витрати? Насправді вам, мабуть, слід попросити свого клієнта прийняти рішення, оскільки він оплачує рахунки та отримує потенційні вигоди. Один з хороших варіантів - спершу скористатися простим рішенням і запропонувати більш складне рішення як можливе вдосконалення. Це дозволяє вам налагодити роботу системи та дати клієнту щось для початку тестування, і цей досвід може повідомити про рішення впровадити (або не реалізувати) більш складне рішення.


2

Оцінюючи два підходи, один простіший, але менш ефективний, а інший - складніший та ефективніший, слід враховувати проблему та область проекту.

Розглянемо багатомільярдний програмний проект для галузі охорони здоров'я, який запланував термін експлуатації протягом понад 15 років технічного обслуговування та +20 років використання. У такому проекті виконання, безумовно, не викликає занепокоєння, але складність та структура проекту можуть спричинити великі проблеми з підтриманням проекту, який триває як мінімум 15 років. Обслуговуваність та простота стають перед усім.

Потім розглянемо інший приклад. Консольний ігровий двигун, який повинен живити майбутні ігри компанії протягом наступних 5 років. Оскільки ігри є надзвичайно обмеженими ресурсами програми, ефективність у багатьох випадках передує ремонтопридатності. Написання власних, дуже специфічних структур даних та алгоритмів для певного завдання може бути дуже важливим, навіть якщо це суперечить будь-яким «найкращим практикам» розробки програмного забезпечення. Хорошим прикладом цього може бути Дизайн, орієнтований на дані, в якому ви зберігаєте свої дані в подібних масивах даних, а не в реальних об'єктах. Це полягає в збільшенні довідки про локальність і як такому підвищенні ефективності кешу процесора. Не практично, але дуже важливо в даній області.


1

Це завжди складне запитання, і я бачу, як відповіді коливаються в одну сторону, тому я буду грати в гру для іншої сторони, хоча я не стверджую, що жодна відповідь є правильною, це дуже м'яка та окрема тема.

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

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

Задокументуйте це в коді, навіть розглянути можливість написання якоїсь реальної документації. Подумайте про складні структури даних та про те, як вони задокументовані, уявіть собі, намагаючись зрозуміти реалізацію одного з них з коду без статті даних про структуру даних книги / wikipedia. І все ж ми всі приймаємо, що ці складні структури даних насправді є добрими речами, і вигідно, щоб хтось реалізував їх на наших мовах.

Пам’ятайте, що всі ми надсилаємо повідомлення на стеку TCP / IP, що, ймовірно, не так сильно, як код може отримати, якщо хтось із нас повинен це подивитися, явно так, що він працює так, як і ми вимагаємо цього. Можливо, для вашої проблеми не потрібен такий рівень оптимізації, можливо, це і є, але будьте обережні, вирішуючи це питання, як це нам доводиться час від часу: там є дракони.


0

Я заходжу над цим, працюючи в районах, де немає домовленостей про домовленості про рівень обслуговування. Що стосується офлайн-рендерів у комп'ютерній графіці, то для користувачів немає "задовільної продуктивності", оскільки вони вже витрачають величезні суми грошей на розподіл обчислень по хмарах та надання ферм навіть із найсучаснішими рендерами виводити якісні зображення та рамки для фільмів, напр

Але я маю сказати, як один, хто працює в цій галузі протягом багатьох років, що будь-яке рішення, що значно погіршує ремонтопридатність на користь ефективності, насправді працює проти постійно змінюваних вимог щодо продуктивності. Тому що, якщо ви не можете ефективно підтримувати своє рішення протягом наступних років, оскільки справи змінюються під вашими ногами (як з точки зору оточуючого коду, так і того, що користувачі очікують, коли конкуренти перевершують один одного), то ваше рішення вже працює в напрямку застарівання і в необхідність оптової заміни.

Я не бачу кінцевої мети профілів на зразок VTune як способу прискорити запуск коду. Їх кінцева цінність полягає в тому, щоб переконатися, що я не знижую свою продуктивність, щоб відповідати постійно зростаючим вимогам продуктивності. Якщо я абсолютно повинен застосувати мікрооптимізацію грубої зовнішності, то профайлер у поєднанні із запуском його у реальних випадках користувачів (а не якийсь тестовий випадок, як я думаю, може бути важливим), гарантує застосування таких неминуче грубого вигляду оптимізація дуже, дуже розумно стосується лише перших топових точок, які з’являються, а також дуже ретельно їх документування, тому що мені неминуче доведеться переглянути і підтримувати, змінювати та змінювати їх на наступні роки, якщо це рішення залишатиметься життєздатним.

І особливо, якщо ваше оптимізоване рішення передбачає більше з'єднань, я справді не бажаю його використовувати. Серед найбільш цінних показників, які я оцінив у найбільш критичних для продуктивності областях бази даних, є розв'язка (як мінімізація кількості інформації, над якою потрібно щось працювати, що також мінімізує ймовірність її необхідності зміни, якщо вона безпосередньо не потребує змін ), оскільки ці критичні області значно примножують причини зміни речі. Що означає, що чим менше інформації потрібно для роботи, тим менше причин для змін, а мінімізація причин змін - це справді величезна частина підвищення продуктивності в моїх конкретних областях, тому що все одно доведеться постійно змінюватись (ми я застаріла через рік в іншому випадку),

Для мене найбільшими та найефективнішими рішеннями, які я знайшов, є ті, де ефективність та ремонтопридатність та продуктивність не є діаметрально протилежними один одному. Завдання мені - спробувати зробити ці поняття такими ж гармонійними, як це можливо зробити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.