Чи впливає довжина функції на продуктивність програміста? Якщо так, то яка хороша максимальна кількість рядків, щоб уникнути втрати продуктивності?
Оскільки це дуже впевнена тема, будь ласка, підкріпіть заяву деякими даними.
Чи впливає довжина функції на продуктивність програміста? Якщо так, то яка хороша максимальна кількість рядків, щоб уникнути втрати продуктивності?
Оскільки це дуже впевнена тема, будь ласка, підкріпіть заяву деякими даними.
Відповіді:
З того моменту, як я взявся за цю божевільну ракетку в 1970 році, я побачив рівно один модуль, який дійсно потребував більше однієї друкованої сторінки (приблизно 60 рядків). Я бачив безліч модулів, які були довші.
З цього приводу я написав модулі, які були довші, але вони, як правило, великі машини з кінцевим станом, написані як великі заяви-комутатори.
Частина проблеми полягає в тому, що програмістів сьогодні не вчать модулювати речі.
Стандарти кодування, які максимально витрачають вертикальний простір, також є частиною проблеми. (Мені ще доводиться зустрічатися з менеджером програмного забезпечення, який прочитав " Психологію комп'ютерного програмування " Джеральда Вайнберга . Вайнберг зазначає, що багаторазові дослідження показали, що розуміння програміста по суті обмежується тим, що програміст може побачити в будь-який момент. Якщо програміст повинен прокручувати або перегортати сторінку, їх розуміння значно падає: вони повинні пам’ятати і абстрагуватися.)
Я все ще переконаний, що багато добре задокументованих приріст продуктивності програміста від FORTH були пов'язані із системою "блокування" FORTH для вихідного коду: модулі були жорстко обмежені абсолютним максимумом 16 рядків з 64 символів. Ви можете розраховувати нескінченно, але ні за яких обставин ви не могли писати розпорядження 17 рядків.
Залежить від мови, якою ви користуєтесь, але загалом (і на мій особистий смак):
Якщо це більше, то це те, що мені потрібно повернутися пізніше і переробити.
Але реально , будь-який розмір, який він повинен бути, коли вам потрібно щось доставити, і що на даний момент є більше сенсу виплюнути їх таким чином, ще простіше іноді когось переглядати перед доставкою. (але все-таки поверніться до цього пізніше).
(Нещодавно моя команда запустила програму на нашій кодовій базі: ми знайшли клас із 197 методами та ще один із 3 методами, але один із них був 600 рядків. Симпатична гра: що гірше за 2 зла?)
Тепер для більш дзен-відповіді ... Взагалі вважається хорошою практикою (TM) цитувати одного або двох великих людей, тож ось:
Все повинно бути зроблено максимально просто, але не простіше. - А. Ейнштейн
Досконалість, нарешті, досягається не тоді, коли більше нічого не можна додати, а коли вже немає чого відняти. - А. де Сент - Екзюпері
Як додаток до цього, ваші функції повинні мати чіткі назви, що пояснюють їх наміри. Щодо коментарів, я зазвичай не коментую функцію:
Блоку коментарів у верхній частині кожної функції (що вимагає пояснення) достатньо. Якщо ваша функція невелика, а імена функцій досить явні, вам слід просто сказати, чого ви хочете досягти і чому. Я використовую вбудовані коментарі лише для полів на деяких мовах або для запуску блоку для функцій, які порушують ці 25 -35 рядкові правила, якщо наміри не зрозумілі. Я використовую коментар до блоку всередині коду, коли трапляються виняткові ситуації (блок лову, де вам нічого не потрібно або хочете щось робити, повинен мати коментар із зазначенням, чому, наприклад).
Детальніше, будь ласка, прочитайте мою відповідь на Стиль та рекомендації коду коментування
tt
для створення цих, але іноді ви застрягли з функцією довгої дупи (або з довгою функцією дупи), яка все одно не робить нічого цікавого, так що це не реальна проблема.
Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3);
, зрозуміло, що все це однаково. (Зауважте, це лише приклад; ця функція час від часу з’являється)
На мою думку, кожна функція повинна бути якомога меншою. Кожна функція повинна робити лише одне і робити це добре. Це насправді не відповідає питання про максимальну довжину, але я більше відчуваю тривалість функцій.
Щоб використати слова дядька Боба, "Витягайте, поки ви просто не зможете витягти більше. Витягайте, поки не кинете".
Якою має бути максимальна висота будівлі? Залежить від того, де знаходиться збірка або висота, яку ви хочете.
Ви можете отримати різні відповіді від різних людей, які приїжджають з різних міст.
Деякі функції сценарію та обробники переривань ядра дуже довгі.
Метод, який працює для мене, такий: Чи можу я частині довшої функції дати ім’я, яке має сенс. Я думаю, що довжина методу не така важлива, як хороша назва. Метод повинен робити те, що говорить назва, не більше і не менше. І ви повинні вміти давати хороше ім’я. Якщо ви не можете назвати свій метод хорошим, код, ймовірно, не є гарним.
Поки йому потрібно робити те, що потрібно робити, але вже не.
Я думаю, що це торгівля. Якщо у вас багато коротких методів, відладкувати їх часто важче, ніж один довгий метод. Якщо вам доведеться стрибати через редактор 20 або 30 різних разів, щоб простежити один виклик методу, важко буде тримати це все в голові. Тим часом, якщо є один добре написаний чіткий метод, навіть якщо це 100 рядків, його часто простіше тримати в голові.
Справжнє питання полягає в тому, чому слід застосовувати предмети різними методами, а відповідь, як зазначено вище, - повторне використання коду. Якщо ви не повторно використовуєте код (або не знаєте), можливо, буде доцільно залишити його в одному гігантському простому для слідування способі, а потім, як вам потрібно повторно використовувати, розділіть частини, які потребують повторного використання. використовуючи більш дрібні методи.
Насправді частиною гарного проектування методів є створення функціонально згуртованих методів (по суті вони роблять одне). Тривалість методів значення не має. Якщо функція робить одну чітко визначену річ і становить 1000 рядків, то це хороший метод. Якщо функція робить 3 або 4 речі і становить лише 15 рядків, то це поганий метод ...
Мені легше відстежувати, що я роблю, якщо я можу побачити всю функцію відразу. Отже, ось як я вважаю за краще писати функції:
Я рідко пишу функції довше цього. Більшість із них - гігантські заяви C / C ++.
Питання має полягати в тому, скільки речей має виконувати функція. І зазвичай буває рідко, що вам потрібно 100 рядків, щоб зробити "одну" річ. Знову ж це залежить від рівня, з якого ви дивитесь коду: чи є хеширование пароля одним? Або хеш-пам'ять і збереження пароля одне?
Я б сказав, почніть зі збереження пароля як однієї функції. Коли ви відчуваєте, що хешування - це інше, і ви перетворюєте код. Я не є експертом-програмістом будь-якими способами, але IMHO, вся ідея функцій починається невеликою, що чим більше атомних ваших функцій, тим більше шанс повторного використання коду, ніколи не потрібно проводити однакові зміни в більш ніж одному місці тощо.
Я бачив процедури, що зберігаються в SQL, що працюють понад 1000 рядків. Чи кількість рядків збережених процедур також менше 50? Я не знаю, але це робить читання коду, пекло. Мало того, що вам потрібно продовжувати прокручування вгору та вниз, вам потрібно дати кілька рядків коду назви, як-от «це робить перевірку1», «це оновлення в базі даних» тощо - робота, яку повинен був виконати програміст.
З цикломатичної складності (Вікіпедія):
Цикломатична складність розділу вихідного коду - це підрахунок кількості лінійно незалежних шляхів через вихідний код.
Я рекомендую вам зберігати це число менше 10 в одному методі. Якщо вона потрапляє до 10, то час переосмислити.
Є інструменти, які дозволяють оцінити ваш код і дати цикломатичну кількість складності.
Ви повинні прагнути інтегрувати ці інструменти у свій конвеєр.
Не переслідуйте буквально розмір методу, а спробуйте переглянути його складність та обов'язки. Якщо на неї покладено більше відповідальності, то, ймовірно, це гарна ідея переоцінити їх. Якщо його цикломатична складність зростає, то, ймовірно, настав час переосмислити.
Я впевнений, що є й інші інструменти, які дають вам подібні відгуки, але я ще не мав можливості вивчити це.
Як правило, я намагаюся дотримуватися своїх методів / функцій тим, що відповідає екрану монітора 1680x1050. Якщо воно не підходить, використовуйте допоміжні методи / функції, щоб розібрати завдання.
Це допомагає читати як на екрані, так і на папері.
Я не ставлю обмеження на жорстку лінію ні на що, оскільки деякі функції реалізують алгоритми, які за своєю суттю є складними, і будь-яка спроба скоротити їх зробить взаємодію між новими, коротшими функціями настільки складними, що в чистому результаті не буде зниження простоти. Я також не вірю, що ідея про те, що функція повинна виконувати лише "одне", є хорошим керівництвом, оскільки "одна річ" на високому рівні абстракції може бути "багато речей" на нижчому рівні.
Для мене функція, безумовно, занадто довга, якщо її довжина спричиняє тонкі порушення DRY зараз, і витягнення частини функції в нову функцію або клас може вирішити це. Функція може бути занадто довгою, якщо це не так, але функцію або клас можна легко витягнути, що зробить код більш модульним таким чином, який, можливо, буде корисним в умовах передбачуваної зміни дороги.
Досить короткий, щоб правильно його оптимізувати
Методи повинні бути такими короткими, щоб робити саме одне. Причина цього проста: так ваш код можна правильно оптимізувати.
У мові JIT-ted, як Java або C #, важливо, щоб ваші методи були простими, щоб компілятор JIT міг швидко створювати код. Більш тривалі, складніші методи вимагають більше часу на JIT. Крім того, компілятори JIT пропонують лише кілька оптимізацій, і від цього виграють лише найпростіші методи. Цей факт навіть був названий у Ефективному C # Білла Вагнера .
Для мови нижчого рівня, наприклад C або C ++, важливим є також використання коротких методів (можливо, десяток або більше рядків), оскільки таким чином ви мінімізуєте потребу в зберіганні локальних змінних в ОЗУ, а не в регістрі. (Aka "Реєстрація розливу". Однак зауважте, що в цьому некерованому випадку відносна вартість кожного виклику функції може бути досить високою.
Навіть у динамічній мові, як у Ruby чи Python, наявність коротких методів також допомагає в оптимізації компілятора. У динамічній мові чим "динамічніша" особливість, тим важче її оптимізувати. Наприклад, довгий метод, який займає X і може повернути Int, Float або String, швидше за все, виконує набагато повільніше, ніж три окремі методи, кожен з яких повертає лише один тип. Це тому, що якщо компілятор точно знає, до якого типу функція повернеться, він може оптимізувати і сайт виклику функції. (Наприклад, не перевіряючи конверсії типів.)
Це дуже залежить від того, що в коді.
Я бачив рутину тисячі ліній, з якою у мене не було проблем. Це було величезне твердження перемикача, жоден варіант не перевищував десятка рядків, і єдиною керуючою структурою в будь-якому варіанті був єдиний цикл. У наші дні це було б написано об’єктами, але тоді це не було варіантом.
Я також дивлюсь на 120 рядків у перемикачі переді мною. Жоден випадок не перевищує 3 рядки - охоронець, завдання та перерва. Це розбір текстового файлу, об'єкти - це не можливість. Будь-яку альтернативу було б важче прочитати.
Більшість компіляторів не враховують довжину функції. Функція повинна бути функціональною, але бути одночасно простою для розуміння, зміни та використання людьми. Виберіть довжину, яка вам найбільше підходить.
Моє загальне правило - функція повинна розміщуватися на екрані. Я знайшов лише три випадки, які, як правило, порушують це:
1) Диспетчерські функції. У старі часи це було звичайним явищем, але більшість із них замінюється спадкоємством об'єктів в наші дні. Хоча об'єкти працюють лише всередині вашої програми, і, таким чином, ви все одно будете бачити випадкові функції диспетчеризації, коли маєте справу з даними, які надходять з інших місць.
2) Функції, які виконують цілу купу кроків для досягнення поставленої мети, і в яких кроки не мають хорошого підрозділу. Ви закінчуєте функцію, яка просто викликає довгий список інших функцій по порядку.
3) Як і номер 2, але там, де окремі кроки настільки малі, що їх просто вводити, а не називати окремо.
Можливо, довжина функції не настільки хороша метрика. Ми намагаємось використовувати цикломатичну складність і для методів, і одне з майбутніх правил контрольного джерела контролю, що цикломатична складність класів і методів повинна бути нижчою за X.
Для методів X встановлено на 30, і це досить жорстко.