Коли оптимізація передчасна?


82

Як сказав Кнут,

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

Це те, що часто виникає у відповідях Stack Overflow на запитання на зразок "який найефективніший механізм циклу", "Методи оптимізації SQL?" ( і так далі ). Стандартна відповідь на ці запитання щодо порад щодо оптимізації полягає у тому, щоб сформулювати свій код і перевірити, чи це проблема спочатку, а якщо ні, то ваша нова техніка не потрібна.

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

Ось відповідна стаття Рендалла Хайда під назвою “Помилка передчасної оптимізації” .


42
Це частково парадоксально , що багато людей , які кричать «Передчасна оптимізація є корінь всіх зол» самі передчасно оптимізована цитата: (продовження)
який - то

22
«Ми повинні забути про невеликі ефективності, скажімо , близько 97% часу: передчасна оптимізація є коренем усього зла Однак ми не повинні втратити наші можливості в цій критичній 3%.» (Дональд Кнут)
деякі

2
Я вважаю, що це сказав CA Hoare. Навіть Кнут так говорить.
jamesh

1
так, Тоні Хоаре спочатку сказав, що "передчасна оптимізація - це корінь усієї злої частини", але Кнут цитував / перефразовував його, додаючи решту, я вважаю
nickf

2
Хоча я згоден, що цитатою є питання, яким найчастіше зловживають і виривають його з контексту, він, за визначенням, завжди правильний через "передчасність" (Однак найчастіше він використовується неправильно як виправдання недбалого дизайну та коду). За визначенням, якщо оптимізація відбулася в найбільш сприятливий момент у розробці, будь то під час проектування чи будь-якої іншої точки, це не було «передчасно».
Лоуренс Дол

Відповіді:


103

Дон Кнут розпочав рух грамотного програмування, оскільки вважав, що найважливішою функцією комп'ютерного коду є передача наміру програміста читачеві-людині . Будь-яка практика кодування, яка ускладнює розуміння вашого коду від імені продуктивності, є передчасною оптимізацією.

Деякі ідіоми, введені в ім'я оптимізації, стали настільки популярними, що всі їх розуміють, і вони стали очікуваними , а не передчасними. Приклади включають

  • Використання арифметики покажчика замість нотації масиву в C, включаючи використання таких ідіом, як

    for (p = q; p < lim; p++)
    
  • Повторне прив'язування глобальних змінних до локальних змінних у Lua, як у

    local table, io, string, math
        = table, io, string, math
    

Окрім таких ідіом, використовуйте ярлики на свій ризик .

Вся оптимізація є передчасною, якщо тільки не

  • Програма занадто повільна (багато людей забувають цю частину).

  • У вас є вимірювання (профіль або подібне), яке показує, що оптимізація може покращити ситуацію .

(Також допустимо оптимізувати для пам'яті.)

Пряма відповідь на питання:

  • Якщо ваша "інша" техніка ускладнює розуміння програми , то це передчасна оптимізація .

РЕДАГУВАТИ : У відповідь на коментарі використання швидкого сортування замість більш простого алгоритму, такого як вставка сортування, є ще одним прикладом ідіоми, яку всі розуміють і очікують . (Хоча, якщо ви пишете власну процедуру сортування замість того, щоб використовувати програму сортування в бібліотеці, можна сподіватися, що у вас є дуже вагома причина.)


13
За вашими визначеннями; якщо реалізацію швидкого сорту важче прочитати і зрозуміти, ніж сортування бульбашок, це передчасна оптимізація. Ви не можете оптимізувати для пам'яті? Спробуйте знайти ті самі приклади для великих розріджених матриць. ІМХО, більша частина оптимізації повинна відбуватися на стадії проектування. я, е, дуже рано.
SmacL

1
@frankodwyer: але збільшення покажчика можливо швидше, ніж збільшення лічильника та використання позначень масиву, і це було б передчасною оптимізацією.
Йоахім Зауер

5
@ Норман: Хоча швидкий сорт зараз повсюдний, це було не тоді, коли його вперше винайшли, і тому QED була передчасною оптимізацією, з якою автор не мав жодного діла, чи не так?
Лоуренс Дол

5
@Software Monkey: Абсолютно. Усі дослідження КС - це марне витрачання грошей платників податків і їх слід негайно припинити.
Норман Ремзі,

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

40

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

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

Тож моя порада, оптимізуйте заздалегідь, виходячи з ваших вимог, а не вашого коду, і зверніть увагу на можливе продовження життя вашого додатка.


6
Я не згоден з вашим висновком "пізно пізно". В основному профілювання потрібно, коли припущення не виконується, а профайлер потрібен, щоб повідомити, ЩО припущення порушено. Наприклад, я виявив, що "видалити символ у позиції 0" для StringBuffers в Java добре працював для тестів junit, але ДУЖЕ повільно для великих рядків. Я не підозрював про цей код, поки профіліст не визначив його винуватцем!
Торбьорн Равн Андерсен

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

@peterchen просто з цікавості, що б ви зробили для "видалення першого символу рядка".
Ghos3t

1
@ user258365: Груба сила полягала б у використанні рядкового подання, яке не потребує копіювання для підрядків. Це "майже тривіально" для незмінних підрахованих рядків. Альтернативно, алгоритмічні зміни, такі як заміна (псевдокод) while (s[0]==' ') s = s.substring(1) for(i=0; i<s.len && s[i]==' '; ++i); s=s.substring(i)--- але для цього потрібні вже відомі потенційні проблеми з продуктивністю (профайлери тут є цінними інструментами для постійного навчання).
peterchen

@ ThorbjørnRavnAndersen, я працював консультантом, щоб допомогти команді завершити проект, проте це було неможливо, оскільки серйозні проблеми з продуктивністю не планувалися (крім коду спагетті). У ньому мала бути представлена ​​хронологічна таблиця з усією історією хворого. Був зроблений єдиний запит на цілі дані, як-от Google Maps, що отримують весь світ. Розробка поганого коду, очікуючи на профілювання, згодом призвела до провалу проекту.
Педро Амарал Куто,

31

Якщо у вас немає профілю, це передчасно.


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

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

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

@haslersn: "Кнут говорив про малу ефективність" Дональд Кнут: "Загальноприйнята думка багатьох сучасних інженерів програмного забезпечення вимагає ігнорувати ефективність у малих; але я вважаю, що це просто надмірна реакція на зловживання (...) встановлених інженерних дисциплін, покращення на 12%, яке легко отримати, ніколи не вважається граничним (...) "
Педро Амарал Куто,

27

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

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

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


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

10

Ось проблема, яку я бачу з усією концепцією уникнення передчасної оптимізації.

Існує розрив між тим, як це говорити і робити.

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

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

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

Отже, це була передчасна оптимізація чи ні?


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

1
"де прості концепції будуть менш елегантними, але цілком достатніми" Складний код рідко буває елегантнішим, ніж простий код, коли простий код відповідає вимогам. (Хоча, я б стверджував, що ви повинні переконатися, що ваш простий код насправді вибухає з чітким зазначенням непідтримуваного стану / вводу, якщо хтось намагається виконати його у більш складному випадку.)
jpmc26,

8

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

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


8

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


7

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

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

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

У відповідь на багато інших коментарів, опублікованих з цього питання: вибір алгоритму! = Оптимізація


6

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

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


2
Насправді, справедлива частина «оптимізації» зводиться до вибору належного алгоритму роботи; це діяльність на високому рівні з результатами на високому рівні - далеко від "малої ефективності" у цитаті Кнута.
Shog9

4

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

Моє визначення передчасної оптимізації - це „витрачені зусилля на код, який, як відомо, не є проблемою продуктивності”. Безумовно, є час і місце для оптимізації. Однак фокус полягає у тому, щоб витратити додаткові витрати лише там, де вони враховують продуктивність програми та коли додаткові витрати перевищують показник продуктивності.

Під час написання коду (або запиту до БД) я прагну писати "ефективний" код (тобто код, який виконує призначену функцію, швидко та повністю з найпростішою логікою.) Зверніть увагу, що "ефективний" код не обов'язково такий самий, як "оптимізований" код. Оптимізація часто вносить додаткову складність у код, що збільшує як витрати на розробку, так і на обслуговування цього коду.

Моя порада: Спробуйте оплатити витрати на оптимізацію лише тоді, коли ви можете кількісно оцінити вигоду.


4

При програмуванні важливий ряд параметрів. Серед них:

  • Читаність
  • Ремонтопридатність
  • Складність
  • Надійність
  • Правильність
  • Продуктивність
  • Час розробки

Оптимізація (підвищення ефективності) часто відбувається за рахунок інших параметрів і повинна бути збалансована проти "втрат" у цих сферах.

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


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

3
Можна сказати, що це охоплюється коректністю. До того ж, "продуктивність" у значенні "якомога швидше" дуже рідко є серед вимог, і навіть справа Оли в тому, що це компроміс з іншими потребами, залишається вірним.
frankodwyer

4

Оптимізація може відбуватися на різних рівнях деталізації, від дуже високого до дуже низького рівня:

  1. Почніть з гарної архітектури, вільного зчеплення, модульності тощо.

  2. Виберіть правильні структури даних та алгоритми для проблеми.

  3. Оптимізуйте для пам'яті, намагаючись помістити більше коду / даних у кеш. Підсистема пам'яті в 10-100 разів повільніша, ніж центральний процесор, і якщо ваші дані потрапляють на сторінку на диск, це в 1000-1000 разів повільніше. Обережність щодо споживання пам’яті, швидше за все, принесе значні переваги, ніж оптимізація окремих інструкцій.

  4. У межах кожної функції використовуйте відповідні оператори контролю потоку. (Перемістіть незмінні вирази за межі корпусу циклу. Найпоширеніше значення поставте спочатку у комутаторі / корпусі тощо)

  5. У кожному твердженні використовуйте найбільш ефективні вирази, що дають правильний результат. (Множення проти зрушення тощо)

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

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

У більшості випадків:

A) Ви можете досягти межі ефективності цілі, виконавши оптимізацію високого рівня, тому не потрібно возитися з виразами.

або

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

З мого досвіду, більшість проблем оптимізації можна вирішити як на рівні архітектури / проектування, так і на основі структури даних / алгоритму. Часто (хоча і не завжди) вимагають оптимізації для розміру пам'яті. Але рідко потрібно оптимізувати логіку управління потоком та вираження. І в тих випадках, коли це насправді необхідно, цього рідко буває достатньо.


3

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

Наприклад, щоб додати до списку Нормана:

  • Використання конкатенації StringBuilder в Java (або C # тощо) замість String + String (у циклі);
  • Уникання циклу в C, як: for (i = 0; i < strlen(str); i++)(оскільки strlen тут - це виклик функції, що кожного разу прогулює рядок, викликається для кожного циклу);
  • Здається, у більшості реалізацій JavaScript це зробити швидше, for (i = 0 l = str.length; i < l; i++)і це все ще читається, так що добре.

І так далі. Але такі мікрооптимізації ніколи не повинні коштувати читабельності коду.


3

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

Я думаю, що "передчасна оптимізація" неймовірно суб'єктивна.

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

Редизайн дорожче, ніж оптимізація дизайну очевидними способами з самого початку.

Очевидно, що деякі дрібниці будуть упущені вперше, але це рідко ключові дизайнерські рішення.

Отже: НЕ оптимізація дизайну - це IMO запах коду сам по собі.


Справа в тому, що вузькі місця часто трапляються в розділах коду, про які ви ніколи не думали, що становлять проблему. Профілювання відмовляється від удаваності та показує фактичні місця витрат програми. Краще робити очевидні речі з самого початку, але для всього іншого існує профілювання.
Кріс Сміт 02

2

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

[...] знову ж таки, це помітна економія на загальній швидкості бігу, якщо, скажімо, середнє значення n дорівнює приблизно 20, і якщо підпрограма пошуку виконується в програмі близько мільйона разів. Такі оптимізації циклу [з використанням gotos] не важкі для вивчення, і, як я вже говорив, вони підходять лише для невеликої частини програми, проте вони часто дають значну економію. [...]

І продовжує:

Загальноприйнята мудрість, якою поділяються багато сучасних інженерів програмного забезпечення, вимагає ігнорувати ефективність роботи малого; але я вважаю, що це просто надмірна реакція на зловживання, які, на їхню думку, практикують безглузді програмісти, які не можуть налагоджувати чи підтримувати свої "оптимізовані" програми. У усталених інженерних дисциплінах покращення на 12%, яке легко отримати, ніколи не вважається граничним; і я вважаю, що та ж точка зору повинна переважати в розробці програмного забезпечення. Звичайно, я б не заважав робити такі оптимізації на одній роботі, але коли мова йде про підготовку якісних програм, я не хочу обмежуватися інструментами, які відмовляють мені в такій ефективності [тобто goto заяви в цьому контексті].

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

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

... а потім ще трохи про важливість інструментів профілювання:

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

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

Проте це була цитата на користь відповідним чином застосованих мікрооптимізацій, коли їх використовує досвідчена рука, що тримає профілі. Сьогоднішній аналогічний еквівалент може виглядати так: "Люди не повинні робити незрячі удари при оптимізації свого програмного забезпечення, але користувальницькі розподільники пам'яті можуть мати величезну різницю, застосовуючи їх у ключових областях для покращення місцевості посилання", або " Рукописний SIMD-код із використанням Повторення SoA насправді важко підтримувати, і ви не повинні використовувати його повсюдно, але він може споживати пам'ять набагато швидше, якщо застосувати його належним чином досвідченою та керованою рукою ".

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

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

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


1

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


1

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


1

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


0

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


0

Як я писав про подібне питання, правилами оптимізації є:

1) Не оптимізуйте

2) (лише для експертів) Оптимізуйте пізніше

Коли оптимізація передчасна? Зазвичай.

Виняток, можливо, у вашому дизайні або в добре інкапсульованому коді, який широко використовується. Раніше я працював над критичним часом кодом (реалізація RSA), коли розгляд асемблера, який створив компілятор, і видалення однієї непотрібної інструкції у внутрішньому циклі дало 30% прискорення. Але пришвидшення використання більш досконалих алгоритмів було на порядок більше, ніж це.

Ще одне питання, яке слід задати собі під час оптимізації, - "чи роблю я тут еквівалент оптимізації для модему на 300 бод?" . Іншими словами, чи закон Мура зробить вашу оптимізацію неактуальною задовго. Багато проблем масштабування можна вирішити, просто кинувши на проблему більше апаратного забезпечення.

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

редагувати: До речі, стосовно пов'язаної статті я б поставив під сумнів багато зроблених припущень. По-перше, це неправда, що закон Мура перестав діяти в 90-х. По-друге, не очевидно, що час користувача цінніший за час програміста. Більшість користувачів (щонайменше) не гаряче використовують кожен доступний цикл процесора, вони, мабуть, чекають, поки мережа щось зробить. Плюс є альтернативні витрати, коли час програміста відволікається від реалізації чогось іншого, до того, щоб уникнути кількох мілісекунд того, що робить програма, поки користувач знаходиться в телефоні. Все, що довше цього, зазвичай не є оптимізацією, це виправлення помилок.

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