Вызов метода Java vs с использованием переменной

Недавно я вошел в дискуссию с моей командой о том, как использовать временные переменные против вызова методов getter. Я давно придерживался мнения, что, если я знаю, что мне придется много раз называть простой метод getter, я бы поставил его в временную переменную, а затем использовал эту переменную. Я думал, что это будет лучше как с точки зрения стиля, так и с точки зрения производительности. Однако мой руководитель отметил, что в Java 4 и более новых версиях это было неверно. Он верит в использование меньшего пространства переменных, поэтому он сказал мне, что использование методов getter имеет очень незначительное влияние на производительность, а не на использование переменной temp, и, следовательно, использование getters было лучше. Однако я не полностью убежден в его аргументах. Ребята, что вы думаете?

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

Они могут улучшить компилятор / время выполнения, чтобы быстрее запускать хороший код, и внезапно ваш «быстрый» код фактически замедляет работу системы.

Компилятор Java и оптимизация времени исполнения обычно обычно являются общепринятыми / читаемыми.

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

Не забывайте, что, назначив значение getSomething () переменной вместо вызова дважды, вы предполагаете, что getSomething () вернул бы то же самое во второй раз, когда вы его вызвали. Возможно, это допустимое предположение в сценарии, о котором вы говорите, но бывают случаи, когда это не так.

Это зависит. Если вы хотите дать понять, что вы используете одно и то же значение снова и снова, я бы присвоил его переменной temp. Я бы сделал так, если бы вызов getter был несколько длинным, например myCustomObject.getASpecificValue() .

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

Различия в производительности очень малы или не существуют.

Если вы сохраняете эволюцию кода, простые геттеры в версии 1.0, как правило, становятся не столь простыми геттерами в версии 2.0.

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

Вот почему с точки зрения DRY-принципала имеет смысл кэшировать значение для повторного использования.

Я не буду жертвовать «читабельностью кода» до нескольких микросекунд.
Возможно, это правда, что геттер работает лучше и может сохранить вам несколько микросекунд во время выполнения. Но я верю, что переменные могут сэкономить вам несколько часов или, возможно, дней, когда наступит время исправления ошибок.

Извините за нетехнический ответ.

Я думаю, что последние версии JVM часто достаточно умны, чтобы автоматически кэшировать результат вызова функции, если выполняются некоторые условия. Я думаю, что функция не должна иметь побочных эффектов и надежно возвращать тот же результат каждый раз, когда он вызывается. Обратите внимание, что это может быть или не быть в случае простых геттеров, в зависимости от того, что другой код в вашем classе делает с значениями поля.

Если это не так, и вызываемая функция выполняет значительную обработку, тогда вам действительно лучше кэшировать ее результат во временной переменной. Хотя накладные расходы на вызов могут быть незначительными, метод «занят» будет есть ваш обед, если вы будете называть его чаще, чем необходимо.

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

Это не стоит, если это просто getFoo() . Кэшируя его в переменную temp, вы не делаете ее намного быстрее и, возможно, задаете проблемы, потому что getFoo() может вернуть другое значение позже. Но если это что-то вроде getFoo().getBar().getBaz().getSomething() и вы знаете, что значение не будет изменено в блоке кода, тогда может возникнуть причина использовать временную переменную для лучшей читаемости.

Замечание общего порядка. В любой современной системе, за исключением ввода-вывода, не беспокойтесь о проблемах с производительностью. Яркие быстрые процессоры и кучи памяти означают, что все остальные проблемы в большинстве случаев совершенно несущественны для реальной производительности вашей системы. [Конечно, есть исключения, такие как кеширующие решения, но они далеки и редки.]

Теперь, придя к этой конкретной проблеме, да, компилятор включит все получатели. Тем не менее, даже это не является фактическим соображением, что действительно важно, так это над всеми читабельностью и streamом вашего кода. Замена локаций локальной переменной лучше, если вызов используется несколько раз, например customer.gerOrder (). GetAddress () лучше фиксируется в локальной переменной.

Виртуальная машина может обрабатывать первые четыре локальные переменные более эффективно, чем любая локальная переменная, объявленная после этого (см. Инструкции lload и lload_ ). Таким образом, кеширование результата (inlined) getter может повредить вашу производительность.

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

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

Я поддерживаю использование переменной temp, если вы уверены, что getter вернет одинаковое значение во всей области. Потому что, если у вас есть переменная с именем длиной 10 или более, получатель выглядит плохо в аспекте читаемости.

Я протестировал его в очень простом коде:

  • создал class с простым getter из int (я пробовал как с конечным, так и с конечным значением для Num, не видел никакой разницы, помните, что в случае num никогда не меняется и …!):

     Num num = new Num(100_000_000); 
  • по сравнению с 2 разными для петель:

     1: for(int i = 0; i < num.getNumber(); ++i){(...)} 2: number = num.getNumber(); for(int i = 0; i < number; ++i){(...)} 

В результате было около 3 миллисов в первой и около 2 миллисов во втором. Таким образом, есть небольшая разница, о чем нельзя беспокоиться о небольших циклах, может быть более проблематично при больших итерациях или если вы всегда называете getter и нуждаетесь в них много. Например, при обработке изображений, если вы хотите быть быстрыми, не используйте повторителей, я бы посоветовал ...

  • Каков самый быстрый способ обмена значениями в C?
  • WPF VirtualizingStackPanel для повышения производительности
  • Снижение производительности String.intern ()
  • простейший инструмент для измерения времени и времени кэша программы C и времени процессора в Linux?
  • Быстрое расстояние Левенштейна в R?
  • Декодирование длины пробега в MATLAB
  • Производительность dynamic_cast?
  • Что более эффективно: System.arraycopy vs Arrays.copyOf?
  • System.IO.FileSystemWatcher для отслеживания папки сетевого сервера - соображения производительности
  • Является ли изменчивая переменная «читается» так же быстро, как обычно?
  • Эффективное вычисление линейной комбинации столбцов data.table
  • Interesting Posts

    Зачем нам на самом деле нужно Private или Protected inheritance в C ++?

    как сохранить и прочитать массив массива в NSUserdefaults в swift?

    Как установить Ubuntu, Windows XP и Windows 7 с нуля в качестве системы с тремя загрузками

    Как фильтровать массив объектов на основе значений во внутреннем массиве с jq?

    Какова точка указателей на функции?

    Bbswitch не отключает дискретную графику

    C #: получить полный размер рабочего стола?

    В C, являются указателями массивов или используются в качестве указателей?

    Запустить MBProgressHUD в другом streamе?

    Использование приложений на устройствах, отличных от iOS?

    Показать ограничения для команды таблиц

    Как я могу сделать курсор в Windows с настройкой нескольких мониторов, так как он перемещается между всеми мониторами с одинаковым разрешением?

    Постоянно вставляйте строки из верхней части страницы в Excel

    Как применить тип к экземпляру NSFetchRequest?

    Как я могу сообщить Moq о возврате задачи?

    Давайте будем гением компьютера.