Що програмісти "мікрооптимізують" на сьогодні? [зачинено]


14

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

Іншими словами, чи можна перейняти найкращу практику до крайнього стану, коли вона більше не додає нічого цінного? А натомість витрачаєш час?

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

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


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



@Macneil, я не знаю, для чого мікропровідники мікрооптимізуються, але у мене не так багато часу. Мої колеги також зайняті (всього мої 2 копійки).
робота

@Job: Ви ніколи не бачили, щоб хтось витрачав час, змінюючи код без причини? Вважайте себе щасливчиком. Нижче наведено два чудових приклади: імена змінних та незначне копіювання коду.
Macneil

1
Питання, як це зараз сказано, - це вдосконалення. Я не можу зняти закрите голосування, але воно закінчиться через кілька днів. Власне, питання приваблює досить гарні відповіді.
Роберт Харві

1
До речі, будь-яка найкраща практика може бути сприйнята настільки крайно, що вона більше не приносить користі.
Роберт Харві

Відповіді:


22

Форматування коду

Don't     get    me   wrong             ,
code      should be   consistent        & 
readable                                , 
but       some   take it         too far.

Так, старі добрі типи змінних та назви змінних потребують власних стовпців у серії оголошень змінних. Ой! Забули додатковий рядок для ініціаторів =і четвертий!
Macneil

[Дарн, було б заявлено, але мій щоденний ліміт досягнуто ...]
Макнейл

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

О Боже. З інших відповідей я сміявся, але ця справді болить :-(
Steve314

2
+1 Я колись працював з бібліотекою, де розробник відмовився зробити свій код const-правильним, оскільки він накрутив його код у форматі стовпця ...
Дін Хардінг

20

Раніше я писав багато асемблерів. Не просто компілятори покращилися, це те, що в більшості апаратних засобів зараз багато логіки, присвяченої виконанню коду поза замовленням. Справжня мікропрограма - це планування, більшість інструкцій на комп’ютері займають декілька машинних годин, щоб отримати результат - а завантаження пам'яті, яке пропускає кеш, може зайняти кілька сотень! Тому ідея полягала в тому, щоб запланувати інші вказівки, щоб зробити щось корисне, а не чекати результату. А сучасні машини можуть видавати кілька інструкцій за годинний період. Після того, як ми почали отримувати HW із виконання замовлень, я виявив, що намагання досягти великої продуктивності при ручному кодуванні стала грою гуртків. По-перше, HW поза замовленням не виконає інструкції у вашому ретельно складеному порядку, нова модна архітектура HW зменшила штраф за неоптимальне планування програмного забезпечення достатньо, щоб компілятор зазвичай був у межах кількох відсотків від вашої продуктивності. Також я з'ясував, що компілятори зараз реалізують відомі, але складності, що створюють хитрощі, такі як розкрутка, завантаження знизу, конвеєрне програмне забезпечення тощо. Підсумок, вам доведеться працювати дуже важко, пропускайте деякі з цих хитрощів, і компілятор б'є вас. Використовуйте їх усі, а кількість інструкцій асемблера вам потрібно збільшити в кілька разів!

Мабуть, навіть важливіше, більшість питань щодо продуктивності стосуються не швидкості випуску інструкцій, а отримання даних у процесор. Як я вже згадував вище, затримка пам’яті зараз становить сотні циклів, і процесор може виконувати кілька інструкцій за тактовий період, тому, якщо програма - і особливо структури даних не розроблені таким чином, щоб швидкість удару кешу була надзвичайно високою, мікроналаштування за інструкцією рівень не матиме окупності. Так само, як кажуть військові типи, любителі говорять про тактику розмов, профі - логістика розмов. Програмування продуктивності зараз становить понад 90% логістики (переміщення даних). І це важко підрахувати, оскільки сучасне управління пам’яттю, як правило, має кілька рівнів кешу, а сторінки віртуальної пам’яті обробляються апаратним блоком, який називається TLB. Також вирівнювання адрес на низькому рівні стає важливим, оскільки фактична передача даних не відбувається в одиницях байтів, або навіть 64-бітні довгі, але вони надходять у одиницях кеш-рядків. Тоді більшість сучасних машин мають апаратне забезпечення, яке намагається передбачити, який рядок кешу пропущений вам може знадобитися найближчим часом, і випускає автоматичні попередні вибори, щоб ввести їх у кеш. Тож реальність така, що з сучасними процесорними процесорами моделі настільки складні, що майже не зрозумілі. Навіть детальний апаратний симулятор ніколи не може відповідати точній логіці мікросхем, тому точна настройка вже неможлива.

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


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

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

10

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

Це піде трохи далі, коли я намагаюся поставити всі твори (програму) в один мовний стиль. Іноді моя думка змінюється, і я переглядаю книгу. :)

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


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

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

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

@grandmaster: Не можу більше погодитися.
Роберт Харві

4
@ right-brainers: Будь ласка, введіть кодів для трейдерів, щоб я також міг прочитати ваш код
Хуан Мендес

10

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

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

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

Звичайно, вимоги мають перевагу.


1
Я працював у компанії, яка через це затонула.
Генрі

2
@Henry - Обіцяю, це не я :)
Tim Post

1
@ Генрі: Ви маєте на увазі, що вони витратили час на оптимізацію речей, які, ймовірно, ніколи не відбудуться, або вони не думали про речі, які, ймовірно, "ніколи" не відбудуться ... поки вони не відбудуться, і це було занадто пізно?
Дін Хардінг

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

1
Компанія витратила занадто багато часу на розробку системи для мільйонів користувачів, коли у них не було 1 користувача. Це, мабуть, було винним. Так, давайте звинувачувати маркетинг, ці хлопці - ідіоти.
Генрі

8

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

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

Багато пупового погляду та обговорення природи помилки вводу-виводу. Якщо ви не можете прочитати файл через мережу, це помилка файлу чи помилка мережі? І так далі.

Одного разу я замінив усі конфат-рядки на String.formatтак, що щорічна помилка файлу не призводить до появи зайвих об'єктів у купі. Це було марно.


3
Це важлива робота. Ціна відмови = повідомлення про помилку відображається на щоденній WTF.
Steve314

7

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


4
+1 за "У мене алергія на повторюваний код". Дивіться також мою відповідь тут: programmers.stackexchange.com/questions/14610/…
Macneil

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

5

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

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

Так, це, мабуть, не має сенсу, якщо файл розміром 3 Гб, але більшість файлів не такі великі (принаймні, не ті, з якими я працюю ;-)).


3
Навіть якщо він становить 3 Гб або більше, 64-розрядна машина може обробляти його віртуальною пам'яттю. Використовуйте файл, відображений на пам’яті, і він навіть не прочитає жодну частину вашого файлу, поки це не потрібно. Майте на увазі, навіть це мікро-оптимізація у звичайному випадку.
Steve314

3

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

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

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

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


Привіт, Грег, дякую за відповідь, але я шукаю те, що програмісти роблять, щоб витрачати час, а не оптимізувати продуктивність виконання. Вище є два чудових приклади: Імена змінних та видалення навіть незначного дублювання коду.
Macneil

3

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

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


2

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

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


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

@Yar - Чому програмісти відрізняються від чого?
Джейсон Бейкер

чому б programmers.= programmers.stackexchange.comвідрізнявся від кожного місця, де ви працювали, де вам довелося пояснити різницю між цими двома поняттями? Будь ласка, поясніть різницю.
Дан Розенстарк

@Yar - Я не знаю, що це буде. Насправді, оскільки справа programmers.se полягає у тому, щоб допомогти програмістам об'єднати знання, я би сподівався, що це не так, щоб люди могли хоч трохи просвітитися моєю відповіддю.
Джейсон Бейкер

2
То яка різниця в / т простоті та спрощеності?
Дан Розенстарк

2

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

Це в принципі. Але принцип - брехун.

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

О, і тоді є логіка "Я це пишу - звичайно, це важлива бібліотека".

О - і до речі. Я ніколи ще не використовував профайлер для керування оптимізацією. Не майте доступу до комерційного і ніколи не формували мотивацію з'ясувати gprof.

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

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

EDIT

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


+1 Ага, так! Цей клас аналізує дуже специфічні та вигадливі аргументи командного рядка мого додатка, але дозвольте відформатувати та повністю задокументувати його, коли Javadoc, тому що, безумовно, інші будуть використовувати це роками! [Потрібно буде подати заявку пізніше, досягла моя щоденна шапка.]
Макнейл

@Macneil - це Doxygen, я маю вас знати. З кожним варіантом я можу знайти ввімкнений, тому кожна маленька функція стає "задокументована" в дратуючих деталях, в комплекті з десятком гарних графіків GraphViz. Дійсно допомагає всім оцінити, наскільки важливий мій код - і роздруківка може нанести шпалери на досить великий офісний блок.
Steve314

1

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

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

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

Твіттер і Facebook приходять до тями :-)


Привіт Стівен, це чудовий коментар до мікрооптимізації, але чи бачите ви якісь сучасні еквіваленти? [Facebook і Twitter - це не "найкраща практика", яку можна перенести занадто далеко.]
Macneil

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

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