Як я можу уникати інтуїції з поганою оптимізацією розробника?


22

Я бачив у статті, яка виклала це твердження:

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

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


1
Це зводиться до "Як я уникаю [покладатися] на інтуїцію [при прийнятті рішень]?" Просто: ви підтверджуєте суворими фактами та даними. Отже, у випадку оптимізації, з точки зору розробника: ви орієнтир.
haylem

Відповіді:


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

По суті, ви повинні вміти доводити іншим, де проблема, і що ця зміна призвела до її відходу.

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


51
Або простіше кажучи: "Щоб уникнути поганої оптимізації інтуїції, не використовуйте інтуїцію. Заміряйте".
Kyralessa

6
Ось чому ваша відповідь, а моя - лише коментар. : P
Kyralessa

2
@Thomas, якщо ви спіраєтеся з читабельністю та ремонтопридатністю, ви не зовсім дивитесь на проблеми з продуктивністю, чи не так?

3
@Thomas, я не згоден. Навіть у межах специфікації вам потрібно ретельно перевірити новий код. Це не потрібно для старого коду. Повернутись.

2
@ Thorbjørn Після налаштування продуктивності вам також потрібно ретельно перевірити новий код. Економити час або пам’ять безглуздо, якщо ви ввели дефект.
Томас Оуенс

10

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

Java робить це досить легко за допомогою інструмента VisualVM , який постачається в комплекті з останніми випусками Java Development Kit (JDK). Ідея полягає в тому, щоб з’ясувати, які методи називаються найбільше і в яких методах ви витрачаєте більшу частину часу, як у своєму коді, так і у зовнішніх бібліотеках. Ви також можете отримати дані про ефективність збирання сміття, щоб ви могли налаштувати колектор і відрегулювати мінімальну / максимум купольного простору, необхідного вашій програмі.


VisualVM не є в JRE, а лише JDK.

1
@ Thorbjørn Равн Андерсен Гарний дзвінок. Я повинен уточнити. Однак якщо ви займаєтесь розробкою Java, у вас зазвичай встановлений JDK (хоча ви, можливо, запускаєте OpenJDK або подібне - я не знаю, чи є вони з VisualVM).
Thomas Owens

1
Я дуже часто перемикаю робочі простори в Eclipse, які потім за замовчуванням застосовуються до JRE, який запустив Eclipse. Оскільки встановити JRE набагато простіше, ніж JDK, ми повільно перейшли до процесу складання мурашок, який включає компілятор Eclipse і тому може працювати на простому JRE. Отже, в наші дні ви можете реально працювати без JDK. VisualVM можна завантажувати окремо, що полегшує використання з даним версією Java, оскільки в Windows 64-розрядних JVM не можна підключатися до 32-бітових JVM і навпаки.

9

Оскільки хтось тут говорить про профілістів, я зупинюся на цій частині питання.

Як розробник може уникнути цієї поганої інтуїції?

Ти. робити. ні. Натомість ви ніколи не оптимізуєтесь на початку .
Повторіть це знову і знову і знову, оскільки це релігійна мантра.

Ви виявите, що це робите, і виявите, що не повинні.
А потім знову.
І знову.

Рання оптимізація є одним з основних гріхів програмістів .

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


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

@Vatine Так, був там. Ні, просто не треба. Робіть те, що відповідає вашій мапі уявлення про проблему. Це може бути найефективніший алгоритм , і я бажаю, щоб цього не було.
ZJR

мені це звучить як принцип ЯГНІ - Ви НЕ ВЖЕ потребуєте!
Е.Л. Юсубов

7

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

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


5

Подивіться також на те, скільки пам’яті використовує ваша програма, а не лише її швидкість та час виконання.

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

Я бачив веб-додатки Java, які були настільки проникливими, що вони запустили свій сервер із місця обміну!

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


1

мій засіб - почати з отримання чітких відповідей на два запитання:

  1. як вимірювати продуктивність (наприклад, вимірювати час завантаження даних )
  2. яке цільове значення (наприклад, завантаження даних тривалістю 3 секунди або менше з 95% впевненістю )

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


1

Я знайшов найкращий антидот для передчасної оптимізації - це цей метод .

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

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


1
І, на жаль, ти можеш нести лише 200 фунтів назад до своєї родини, тому не бій білок цілий день.
Йордан

1

Старе запитання, але я запропоную цю відповідь, яка значно відрізняється від інших.

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

Все інше - це передчасна оптимізація і вимагає вашої інтуїції, що часто неправильно.


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

0

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

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

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

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

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

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


0

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

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

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

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

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

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