Де ви оптимізуєте?


9

Існує дві області для оптимізації швидкості в:

  • Там, де проводиться найбільше часу
  • Код, який називається найбільше

Яке найкраще місце для початку оптимізації?

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


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

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

Ні. Шукайте код, який знаходиться у стеці велику частину часу.
Майк Данлаве

Відповіді:


4

Ви повинні ігнорувати низьку ефективність у 95% часу. Спочатку змусьте його правильно працювати , потім проаналізуйте ...

Ваш дизайн.

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

Наприклад, у 3D-грі: якщо ви почнете з простого плоского списку об’єктів для вашої графіки сцени, ви побачите надзвичайно низьку ефективність відносно невеликої кількості об’єктів; але якщо замість цього застосувати ієрархію обсягу (наприклад, octree або BVH) та вирізати частини дерева під час малювання, ви побачите масове підвищення продуктивності.

Коли ваш дизайн здається правильним, ви можете перейти до ...

Логіка низького рівня.

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

У цей момент проаналізуйте і знайдіть місце, де проводиться більшість часу програми, і знайдіть спосіб її усунення.


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

1
@Michael: У такому випадку настав час отримати інструмент профілювання для аналізу деяких типових програм програми та визначити розділи коду, які працюють найповільніше. Я б дуже рекомендував використовувати для цього інструмент. Ви можете зробити певну суму за інтуїцією, але іноді ви знайдете сюрприз, коли це API, який викликає значну кількість часу, а не власний код. У такому випадку, час заглянути в API і побачити, які інші функції доступні, або, якщо ви повинні написати власну функцію заміни ... Фактична свиня продуктивності не завжди є підозрюваною свиней продуктивності ...
FrustratedWithFormsDesigner

1
У нас є інструмент профілювання. Я досі її вивчаю і що робити з інформацією. Це порівняно нова тема для мене і дуже цікава.
Майкл К

@Michael: Добре! Ви знаходитесь (сподіваємось), ваш шлях до успішної настройки продуктивності! :)
FrustratedWithFormsDesigner

+1: Це те, що я збирався сказати, але набагато красномовніше.
Домінік МакДоннелл

3

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

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

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

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

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

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


2

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

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

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


1

Добре "ми" зазвичай не оптимізуємо, поки не буде очевидна потреба в оптимізації, коли щось неприпустимо повільно.

І коли ця потреба виявляється, вона зазвичай несе в собі добрі підказки щодо того, що саме вимагає оптимізації.

Тож відповідь звичайний: "Це залежить".


1

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

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


1

Проблема в тому, що словосполучення «де проводиться найбільше часу» неоднозначне.

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

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

Проблема з поняттям "код, який називається найбільше", полягає в тому, що кількість часу, яке він займає, є результатом того, як часто він викликається і скільки часу займає один виклик (включаючи калледи і введення / виведення). Оскільки кількість часу, яке вона займає, може змінюватись на кілька порядків, кількість разів, яку вона викликає, не говорить про те, наскільки це проблема. Функцію A можна викликати 10 разів і зайняти 0,1 секунди, тоді як функцію B можна викликати 1000 разів і взяти мікросекунду.

Одна річ , яка буде сказати вам , де шукати це: Всякий раз , коли рядок коду викликає час витрачатися саме на стеку . Так, наприклад, якщо рядок коду є гарячою точкою, або якщо це виклик до функції бібліотеки, або якщо це 20-й дзвінок у дереві дзвінків 30 рівня, якщо він відповідає за 20% часу , то це на стеці 20% часу. Зразки стека випадкових випадків матимуть 20% шансів відобразити його. Більше того, якщо зразки можна взяти під час вводу-виводу, вони покажуть, що пояснює введення-виведення, яке може бути таким же або більш марним, як і витрачені цикли процесора.

І це абсолютно незалежно від того, скільки разів його викликають.


Під поняттям "щоденний програміст ніколи не повинен торкатися", ти не маєш на увазі не торкатися? Крім того, чи є вибірка стека практичним методом профілювання?
Майкл К

@Michael: Так, вибірка стека - це метод, на якому базуються сучасні профілі, такі як Zoom . Крім того, повністю ручний працює на диво добре .
Майк Данлаве

Дуже цікаво. У мене зараз є щось навчання!
Майкл К

@Michael: Це як юридична концепція спільної відповідальності. У певний момент часу відповідальність за ПК, який знаходиться в інструкції, покладається на спільну відповідальність не тільки цієї інструкції, але і кожного виклику над нею в стеці. Усунення будь-якого з них запобігло б потраплянню в цей конкретний стан.
Майк Данлаве

0

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


0

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

Ви зробили вимірювання, щоб ви знали, який код займає найбільше часу?


0

Раніше я робив бенчмаркінг та маркетинг для продавця суперкомп'ютерів, тому перемогу над конкуренцією швидко не було найважливішою справою, це було ТІЛЬКО. Такий результат вимагає використання комбінації хорошого алгоритму та структури даних, яка дозволить найбільш інтенсивним процесорам частинам ефективно виконувати пік. Це означало, що ви повинні мати гарне уявлення про те, якими будуть найбільш обчислювальні операції, і які види структур даних дозволять їм працювати найшвидше. Тоді мова йшла про побудову програми навколо тих оптимізованих ядер / структур даних.

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

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


0

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

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

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

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


0

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

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

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

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

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

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

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