Влияет ли длина функции на производительность программиста? Если да, то какое максимальное количество строк нужно избежать, чтобы избежать потери производительности?
Так как это очень мнительная тема, пожалуйста, подкрепите заявку некоторыми данными.
programming-practices
coding-standards
Peter Mortensen
источник
источник
Ответы:
С тех пор, как я начал эту сумасшедшую ракетку в 1970 году, я увидел ровно один модуль, который действительно должен был составлять более одной печатной страницы (около 60 строк). Я видел много модулей, которые были длиннее.
В связи с этим я написал модули, которые были длиннее, но обычно это были большие конечные автоматы, написанные как большие операторы switch.
Частично проблема заключается в том, что программистов в наши дни не учат модульности.
Стандарты кодирования, которые максимизируют трата вертикального пространства, также являются частью проблемы. (Мне еще предстоит встретиться с менеджером по программному обеспечению, который прочитал « Психологию компьютерного программирования » Джеральда Вайнберга . Вайнберг отмечает, что многочисленные исследования показали, что понимание программистом, по существу, ограничено тем, что программист может видеть в любой данный момент. программист должен прокрутить или перевернуть страницу, их понимание значительно падает: они должны помнить и абстрагироваться.)
Я по-прежнему убежден, что значительная часть хорошо документированных приростов производительности труда программистов от FORTH произошла благодаря «блочной» системе исходного кода FORTH: модули были жестко ограничены абсолютным максимумом в 16 строк по 64 символа. Вы могли бы учитывать бесконечно, но вы ни при каких обстоятельствах не могли написать подпрограмму из 17 строк.
источник
Какой правильный размер, правда?
Зависит от языка, который вы используете, но в целом (и на мой личный вкус):
Если это больше, то это то, что мне нужно вернуться позже и переделать.
Но реально , любого размера она должна быть , когда вам нужно поставить что - то , и что это имеет смысл на данный момент , чтобы выплюнуть их , как это, делает его еще проще иногда для кого - то перед транспортировкой. (но все же вернемся к этому позже).
(Недавно моя команда запустила программу на нашей базе кода: мы нашли класс с 197 методами, а другой - только с 3 методами, но один из них был 600 строками. Симпатичная игра: что хуже из 2 зол?)
Теперь для более дзенского ответа ... Вообще считается хорошей практикой (ТМ) цитировать одного или двух великих людей, так что вот так:
Приложение к стилю комментариев
В дополнение к этому ваши функции должны иметь четкие имена, объясняющие их назначение. Что касается комментариев, я обычно не комментирую внутри функции:
Блок комментариев в верхней части каждой функции (который требует объяснения) достаточно. Если ваша функция небольшая, а имена функций достаточно явные, вам просто нужно сказать, чего вы хотите достичь и почему. Я использую встроенные комментарии только для полей в некоторых языках или для запуска блоков для функций, которые нарушают правила строки 25-35, если намерение неясно. Я использую блочный комментарий внутри кода, когда возникают исключительные ситуации (например, блок catch, в котором вы не нуждаетесь или не хотите что-либо делать, должен содержать комментарий, объясняющий почему).
Для более подробной информации, пожалуйста, прочитайте мой ответ по стилю и рекомендации комментирования кода
источник
tt
для генерации, но иногда вы застряли с длинной задницей (или с длинной задницей), которая на самом деле ничего не делает, так что не является реальной проблемой.Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3);
, ясно, что все совершенно одинаково. (Обратите внимание, что это всего лишь пример; такая функция время от времени появляется)На мой взгляд, каждая функция должна быть как можно меньше. Каждая функция должна делать только одно и делать это хорошо. Это на самом деле не отвечает на вопрос о максимальной длине, но это больше мои чувства по поводу длины функций.
Чтобы использовать слова дяди Боба: «Извлекай, пока больше не сможешь извлечь. Извлеки, пока не упадешь».
источник
Какой должна быть максимальная высота здания? Зависит от того, где находится сборка, или от высоты, которую вы хотите, чтобы она была.
Вы можете получить разные ответы от разных людей из разных городов.
Некоторые функции сценариев и обработчики прерываний ядра очень длинные.
источник
Метод, который работает для меня: могу ли я иметь часть более длинной функции, дающую имя, которое имеет смысл. Я думаю, что длина метода не так важна, как хорошее именование. Метод должен делать то, что говорит название, не больше и не меньше. И вы должны быть в состоянии дать хорошее имя. Если вы не можете назвать свой метод хорошим, код, вероятно, не очень хороший.
источник
Пока это нужно, чтобы делать то, что нужно, но больше не нужно.
источник
Я думаю, что есть компромисс. Если у вас много коротких методов, отладить их часто сложнее, чем один длинный метод. Если вам придется прыгать по редактору 20 или 30 раз, чтобы отследить один вызов метода, вам будет сложно держать все это в голове. Между тем, если есть один хорошо написанный понятный метод, даже если он содержит 100 строк, его часто легче держать в голове.
Реальный вопрос заключается в том, почему элементы должны быть разными методами, и ответ, как указано выше, - повторное использование кода. Если вы не используете код повторно (или не знаете), то, возможно, имеет смысл оставить его в одном гигантском методе, которому легко следовать, и затем, когда вам потребуется его повторно использовать, разделите части, которые нужно повторно использовать. используя в меньшие методы.
На самом деле частью хорошего метода разработки является создание функционально связанных методов (по сути, они делают одно). Длина методов не имеет значения. Если функция выполняет одну четко определенную вещь и имеет 1000 строк, то это хороший метод. Если функция делает 3 или 4 вещи и только 15 строк, то это плохой метод ...
источник
Мне легче отслеживать, что я делаю, если я вижу всю функцию одновременно. Итак, вот как я предпочитаю писать функции:
Я редко пишу функции дольше, чем это. Большинство из них - гигантские операторы переключения C / C ++.
источник
Для меня функция - это любая длина, которой она должна быть. Большую часть времени я делю это на то, когда я буду повторно использовать код.
В основном, я буду придерживаться принципа «высокая когезия, низкая связь», и нет никаких ограничений на длину.
источник
Вопрос должен состоять в том, сколько функций должна выполнять функция. И, как правило, редко требуется 100 строк, чтобы сделать «одну» вещь. Опять же, это зависит от уровня, с которого вы смотрите на код: хэширование пароля - это одно? Или хеширование и сохранение пароля - это одно?
Я бы сказал, начать с сохранения пароля в качестве одной функции. Когда вы чувствуете, что хеширование отличается, и вы реорганизуете код. Я ни в коем случае не являюсь опытным программистом, но ИМХО, вся идея функций начинается с малого: чем более элементарны ваши функции, тем выше вероятность повторного использования кода, никогда не делая одинаковых изменений в более чем одном месте , так далее.
Я видел хранимые процедуры SQL, которые запускают более 1000 строк. Число строк хранимых процедур также меньше 50? Я не знаю, но это делает чтение кода, черт возьми. Вы не только должны продолжать прокручивать вверх и вниз, вам нужно дать нескольким строкам кода имя типа «это делает валидацию1», «это обновляет базу данных» и т. Д. - работу, которую должен был выполнить программист.
источник
Из цикломатической сложности (Википедия):
Я рекомендую вам сохранить это число до 10 в одном методе. Если он доходит до 10, то пришло время пересмотреть.
Существуют инструменты, которые могут оценить ваш код и дать вам число цикломатической сложности.
Вы должны стремиться интегрировать эти инструменты в свой конвейер сборки.
Не буквально преследуйте размер метода, но попытайтесь взглянуть на его сложность и обязанности. Если на него лежит более одной ответственности, то, вероятно, это хорошая идея для перефакторинга. Если его цикломатическая сложность возрастает, то, вероятно, пришло время пересмотреть фактор.
Я вполне уверен, что есть и другие инструменты, которые дают вам аналогичные отзывы, но у меня еще не было возможности изучить это.
источник
Обычно я стараюсь, чтобы мои методы / функции соответствовали экрану монитора 1680x1050. Если он не подходит, то используйте вспомогательные методы / функции для разделения задачи.
Это помогает удобочитаемости как на экране, так и на бумаге.
источник
Я не ставлю жесткие ограничения на что-либо, потому что некоторые функции реализуют алгоритмы, которые по своей природе являются сложными, и любая попытка сделать их короче сделает взаимодействие между новыми, более короткими функциями настолько сложным, что общий результат не уменьшит простоту. Я также не верю, что идея о том, что функция должна выполнять только «одну вещь», является хорошим руководством, поскольку «одна вещь» на высоком уровне абстракции может быть «многими вещами» на более низком уровне.
Для меня функция определенно слишком длинная, если ее длина прямо сейчас вызывает незначительные нарушения DRY, и извлечение части функции в новую функцию или класс может решить эту проблему. Функция может быть слишком длинной, если это не так, но функция или класс могут быть легко извлечены, что сделает код более модульным, что может оказаться полезным в условиях ожидаемых изменений в будущем.
источник
Достаточно короткий, чтобы быть правильно оптимизированным
Методы должны быть настолько короткими, чтобы делать ровно одну вещь. Причина этого проста: ваш код может быть должным образом оптимизирован.
В языке JIT-ted, таком как Java или C #, важно, чтобы ваши методы были простыми, чтобы JIT-компилятор мог быстро создавать код. Более длинные, более сложные методы, естественно, требуют больше времени JIT. Кроме того, JIT-компиляторы предлагают только несколько оптимизаций, и от этого выигрывают только самые простые методы. Этот факт был даже назван в Эффективном C # Билла Вагнера .
В языке более низкого уровня, таком как C или C ++, наличие коротких методов (может быть, дюжина или около того строк) также важно, потому что таким образом вы минимизируете необходимость хранения локальных переменных в оперативной памяти, а не в регистре. (Также известный как «Регистрация разливов».) Обратите внимание, что в этом неуправляемом случае относительная стоимость каждого вызова функции может быть довольно высокой.
И даже в динамическом языке, таком как Ruby или Python, наличие коротких методов также помогает в оптимизации компилятора. В динамическом языке, чем более «динамична» функция, тем сложнее ее оптимизировать. Например, длинный метод, который принимает X и может вернуть Int, Float или String, вероятно, будет работать намного медленнее, чем три отдельных метода, каждый из которых возвращает только один тип. Это связано с тем, что, если компилятор точно знает, какой тип будет возвращать функция, он также может оптимизировать сайт вызова функции. (Например, не проверка на преобразование типов.)
источник
Это очень сильно зависит от того, что в коде.
Я видел рутину из тысячи строк, с которой у меня не было проблем. Это был огромный оператор switch, ни один параметр не превышал дюжину строк, и единственной структурой управления в любом варианте был один цикл. В наши дни это было бы написано объектами, но тогда это было невозможно.
Я также смотрю на 120 линий в коммутаторе передо мной. Ни один случай не превышает 3 строки - охранник, назначение и перерыв. Это анализ текстового файла, объекты не возможны. Любую альтернативу будет сложнее читать.
источник
Большинство компиляторов не обращают внимания на длину функции. Функция должна быть функциональной, но при этом быть легкой для понимания, изменения и повторного использования для людей. Выберите длину, которая подходит вам лучше всего.
источник
Мое общее правило заключается в том, что функция должна помещаться на экране. Я нашел только три случая, которые имеют тенденцию нарушать это:
1) Диспетчерские функции. В старые времена они были распространены, но большинство из них заменены наследованием объектов в эти дни. Тем не менее, объекты работают только внутри вашей программы, и, таким образом, вы все равно увидите случайные функции отправки при работе с данными, поступающими из других мест.
2) Функции, которые выполняют целую кучу шагов для достижения цели и в которых шагам не хватает хорошего подразделения. В итоге вы получаете функцию, которая просто вызывает по очереди длинный список других функций.
3) Как # 2, но где отдельные шаги настолько малы, что они просто встроены, а не вызваны отдельно.
источник
Может быть, длина функции не очень хорошая метрика. Мы пытаемся использовать цикломатическую сложность , также и в методах, и одно из будущих правил контроля исходного кода, согласно которому цикломатическая сложность в классах и методах должна быть ниже X.
Для методов X установлен на 30, и это довольно сложно.
источник