TD; DR:
Була певна плутанина щодо того, що я просив, тож ось ідея, яка рухає за питанням:
Я завжди мав намір питання бути таким, яким воно є. Я, можливо, не сформулював це добре спочатку. Але намір завжди був " модульний, відокремлений, вільний зв'язаний, роз'єднаний, реконструйований код " помітно повільніше за своєю природою, ніж " монолітний одноодиничний, зробіть все в одному місці, один файл, щільно пов'язаний " код. Решта - це лише деталі та різноманітні прояви цього, на які я стикався тоді чи зараз, або згодом. У певному масштабі це точно повільніше. Як і диск, що не відшаровується, вам потрібно збирати шматки звідусіль. Це повільніше. Напевно. Але я повинен дбати?
І питання не в тому ...
не про мікрооптимізацію, передчасну оптимізацію тощо. Це не про "оптимізацію тієї чи іншої частини до смерті".
Що це тоді?
Йдеться про загальну методологію та прийоми та способи мислення про написання коду, що з’явився з часом:
- "ввести цей код у свій клас як залежність"
- "написати один файл у клас"
- "відокремити свій погляд від бази даних, контролера, домену".
- не пишіть спагетті однорідного кодового блоку, але пишіть багато окремих модульних компонентів, які працюють разом
Йдеться про спосіб і стиль коду, який зараз - протягом цього десятиліття - бачать та обстоюють у більшості рамок, виступають на конвенціях, передаються через громаду. Це зміна мислення від «монолітних блоків» до «мікросервісів». І з цим приходить ціна в плані продуктивності на рівні машини та накладних витрат, а також на деяких накладних на рівні програміста.
Оригінальне запитання наступне:
У галузі комп'ютерних наук я помітив помітне зрушення в мисленні, коли мова йде про програмування. Я досить часто зустрічаю поради, які виглядають так:
- писати менший функціональний код (більш тестований та підтримуваний таким чином)
- рефактор існуючого коду на все менші і менші шматки коду, поки більшість ваших методів / функцій не мають лише кілька рядків, і зрозуміло, яке їх призначення (що створює більше функцій порівняно з більшим монолітним блоком)
- писати функції, які виконують лише одне - роз'єднання проблем тощо (що зазвичай створює більше функцій та більше кадрів на стеку)
- створити більше файлів (один клас на файл, більше класів для розкладання, для цілей шару, таких як MVC, архітектура домену, шаблони дизайну, OO тощо), що створює більше викликів файлової системи)
Це зміна в порівнянні зі «старими» або «застарілими» або «спагетті» методами кодування, де у вас є методи, що охоплюють 2500 рядків, а великі класи та об'єкти бога роблять все.
Моє запитання таке:
коли виклик зводиться до машинного коду, до 1s і 0s, до інструкцій по збірці, до платівок жорсткого диска, чи повинен я взагалі стурбований тим, що мій ідеально відокремлений клас OO з різноманітними відреставрованими дрібними та крихітними функціями та методами також генерує набагато зайвих накладних витрат?
Деталі
Хоча я не дуже добре знайомий з тим, як в кінцевому підсумку обробляється код OO та його виклики методів, і як виклики БД та виклики компілятора переводяться на переміщуючу ручку виконавчого механізму на платівці жорсткого диска, у мене є певна ідея. Я припускаю, що кожен виклик додаткової функції, виклик об'єкта або виклик "#include" (на деяких мовах) генерують додатковий набір інструкцій, тим самим збільшуючи об'єм коду та додаючи різні накладні витрати "проводка коду", не додаючи фактичного "корисного" коду . Я також уявляю, що хороші оптимізації можна зробити ASM ще до того, як він фактично запуститься на апаратному забезпеченні, але оптимізація може зробити також дуже багато.
Отже, моє запитання - скільки накладних витрат (у просторі та швидкості) фактично вводить добре відокремлений код (код, розбитий на сотні файлів, класів та шаблонів дизайну тощо), порівняно із тим, що є "один великий метод, який містить все в одному монолітному файлі ", через цю накладну?
ОНОВЛЕННЯ для наочності:
Я припускаю, що прийняття одного і того ж коду та розбиття його, рефакторинг, декомпозиція його на все більше функцій та об'єктів, методів і класів призведе до того, що все більш і більше параметрів передаватимуться між меншими фрагментами коду. Тому що, безумовно, код рефакторингу повинен тримати потік потоку, і це вимагає передачі параметрів. Більше методів або більше класів або більше моделей проектування заводських методів призводить до того, що більше витрат на передачу різних бітів інформації більше, ніж це стосується одного монолітного класу або методу.
Десь було сказано (цитуйте TBD), що до 70% всього коду складається з інструкції MOV ASM - завантаження регістрів процесора з належними змінними, а не власне обчислення. У моєму випадку ви завантажуєте час процесора за допомогою інструкцій PUSH / POP, щоб забезпечити зв'язок та параметри, що проходять між різними фрагментами коду. Чим менше ви будете робити свої шматочки коду, тим більше потрібно накладних "зв'язків". Я стурбований тим, що ця зв'язок додає розростання та уповільнення програмного забезпечення, і мені цікаво, чи варто мені це турбувати, і скільки, якщо взагалі є, тому що нинішні та майбутні покоління програмістів, які будують програмне забезпечення для наступного століття , доведеться жити і споживати програмне забезпечення, побудоване за цими методами.
ОНОВЛЕННЯ: Кілька файлів
Я зараз пишу новий код, який повільно замінює старий код. Зокрема, я зазначив, що один із старих класів був файлом рядків ~ 3000 (як згадувалося раніше). Тепер він стає набором з 15-20 файлів, розташованих у різних каталогах, включаючи тестові файли та не включаючи рамки PHP, які я використовую, щоб зв’язати деякі речі разом. Також надходить більше файлів. Що стосується вводу / виводу диска, завантаження декількох файлів відбувається повільніше, ніж завантаження одного великого файлу. Звичайно, не всі файли завантажуються, вони завантажуються у міру необхідності, а також є кешування дисків та кешування пам’яті, і все ж я вважаю, що це loading multiple files
потребує більшої обробки, ніж loading a single file
у пам’яті. Я додаю це до своєї стурбованості.
ОНОВЛЕННЯ: Залежність Введіть все
Повернувшись до цього через деякий час .. Я думаю, що моє запитання було зрозуміло неправильно. А може, я вирішив неправильно зрозуміти деякі відповіді. Я не говорю про мікрооптимізацію, як окремі відповіді виділили (принаймні, я думаю, називати те, що я говорю про мікрооптимізацію - це неправильно), а про рух "коду Refactor для послаблення жорсткої муфти", в цілому , на кожному рівні коду. Я приїхав із Zend Con зовсім недавно, де цей стиль коду був одним із основних моментів і центральних пунктів конвенції. Розв'яжіть логіку з виду, перегляньте з моделі, модель з бази даних, і, якщо можете, від'єднайте дані з бази даних. Dependency - Введіть все, що іноді означає просто додавання коду проводки (функції, класи, панель котла), що нічого не робить, але служить точкою шва / гачка, в більшості випадків легко збільшується вдвічі розмір коду.
ОНОВЛЕННЯ 2: Чи "розділення коду на більше файлів" суттєво впливає на продуктивність (на всіх рівнях обчислень)
Як філософія compartmentalize your code into multiple files
впливає на обчислення на сьогодні (продуктивність, використання диска, управління пам’яттю, завдання обробки процесора)?
Я говорю про
Перед ...
У гіпотетичному, але цілком реальному не настільки далекому минулому, ви можете легко написати один моноблок файлу, який має модель і вигляд та контролер спагетті або не-спагетті, кодований, але він запускає все, як тільки він уже завантажений. Здійснюючи деякі орієнтири в минулому за допомогою коду С, я виявив, що набагато швидше завантажувати в пам'ять один 900 Мбіт-файл і обробляти його великими шматками, ніж це завантажувати купу менших файлів і обробляти їх у меншій кількості спокійних страв шматки, що зрештою виконують ту саму роботу.
.. А зараз*
Сьогодні я виявляю код, який показує головну книгу, яка має такі функції, як .. якщо елемент є "замовленням", покажіть HTML-блок замовлення. Якщо позицію можна скопіювати, надрукуйте блок HTML, який відображає піктограму та параметри HTML, що дозволяють зробити копію. Якщо елемент можна переміщувати вгору або вниз, відобразіть відповідні стрілки HTML. І т. Д. Я можу через Zend Framework створитиpartial()
call, що по суті означає "викликати функцію, яка приймає ваші параметри та вставляє їх в окремий файл HTML, який він також викликає". Залежно від того, наскільки детально я хочу отримати, я можу створити окремі функції HTML для найдрібніших частин книги. Один для стрілок вгору, стрілка вниз, друга для "чи можу я скопіювати цей елемент" тощо. Легке створення декількох файлів лише для відображення невеликої частини веб-сторінки. Беручи мій код і позакулісний код Zend Framework, система / стек, ймовірно, викликає близько 20-30 різних файлів.
Що?
Мене цікавлять аспекти, зношеність машини, яка створюється шляхом розподілу коду на багато менших окремих файлів.
Наприклад, завантаження більшої кількості файлів означає розміщення їх у різних місцях файлової системи та в різних місцях фізичного жорсткого диска, що означає більше часу на пошук та читання жорсткого диска.
Для процесора це, ймовірно, означає більше контекстної комутації та завантаження різних регістрів.
У цьому підблоці (оновлення №2) мене більш чітко цікавить, як використання декількох файлів для виконання тих же завдань, які можна виконати в одному файлі, впливає на продуктивність системи.
Використання API Zend Form vs простого HTML
Я використовував API Zend Form з останніми та найкращими сучасними методами ОО, щоб створити HTML-форму з валідацією, перетворившись POST
в об'єкти домену.
На це мені знадобилося 35 файлів.
35 files =
= 10 fieldsets x {programmatic fieldset + fieldset manager + view template}
+ a few supporting files
Все це можна замінити кількома простими HTML + PHP + JS + CSS файлами, можливо, всього 4 легкими файлами.
Чи краще? Чи варто? ... Уявіть, що ви завантажуєте 35 файлів + численні файли бібліотек Zend Zramework, які змушують їх працювати проти 4 простих файлів.