Когда я должен учитывать влияние на производительность вызова функции? - PullRequest
3 голосов
/ 17 февраля 2011

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

Мой приятель-программист вместо этого настаивал на том, что влияние этих вызовов функций на производительность было неприемлемым.

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

Ответы [ 7 ]

3 голосов
/ 17 февраля 2011

"Мой приятель-программист вместо этого настаивал на том, что влияние этих вызовов функций на производительность было неприемлемым."

... на что правильный ответ " Докажите. "

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

ИМХО, если у вас нет позиции, которую вы бы предпочли потратить пару часов на написание рутины, которая может бытьЕсли вы используете код для вставки и вставки кода продолжительностью более 10 секунд, вы не должны называть себя кодером.

2 голосов
/ 17 февраля 2011

Современные компиляторы языков, таких как Java, в любом случае будут включать определенные вызовы функций.Мое мнение таково, что дизайн намного важнее тех немногих инструкций, которые были потрачены на вызов функции.Единственная ситуация, о которой я могу подумать, - это написать действительно хорошо настроенный код на ассемблере.

2 голосов
/ 17 февраля 2011

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

1 голос
/ 17 февраля 2011

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

1 голос
/ 17 февраля 2011

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

Учитывая колоссальное увеличение скорости процессора и ресурсов памяти за последние два десятилетия, я предлагаю, чтобы эти проблемы перестали быть такими же актуальными, как раньше.

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

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

Я полагаю, что в большинстве случаев вы обнаружите, что рефакторинг кода в вызовы отдельных функций будет иметь незначительное влияние.Могут быть случаи, когда есть влияние.Однако, правильное ИСПЫТАНИЕ рефакторинга покажет это.В этом меньшинстве случаев ваш друг может быть прав.Большую часть остального времени я предлагаю, чтобы ваш друг немного привязался к методам, предшествующим большинству современных процессоров и носителей информации.

1 голос
/ 17 февраля 2011

Вам нужно задать себе несколько вопросов:

  1. Стоимость времени, потраченного на оптимизацию кода, по сравнению с затратами большего количества оборудования.
  2. Как это влияет на ремонтопригодность?
  3. Как движение в любом направлении влияет на ваш крайний срок?
  4. Действительно ли это требует оптимизации, когда многие современные компиляторы все равно сделают это для вас?Не пытайтесь перехитрить компилятор.

И, конечно, что поможет вам лучше спать по ночам?:)

0 голосов
/ 17 февраля 2011

для семейства c / c ++:

«стоимость» звонка не важна. если он должен быть быстрым, вам просто нужно убедиться, что компилятор может его встроить. это означает, что:

  • тело должно быть видно компилятору

  • тело действительно достаточно маленькое, чтобы считаться встроенным кандидатом.

  • метод не требует динамической отправки

Есть несколько способов сломать эту способность по умолчанию. например:

  • огромное количество команд уже в месте вызова. даже при раннем встраивании компилятор может вывести тривиальную функцию из строки (даже если он может генерировать больше инструкций / более медленное выполнение). раннее встраивание - это способность компилятора встроить функцию на ранней стадии, когда он видит, что вызов стоит больше, чем встроенный.

  • рекурсии

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

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

как есть, и если производительность имеет решающее значение, у вас действительно есть два варианта:

1) научиться писать хорошо организованные программы для скорости. недостаток: больше времени компиляции

2) поддерживать плохо написанную программу

Я предпочитаю 1. любой день.

(да, я потратил много времени на написание программ, критичных к производительности)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...