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

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

46
задан Seagull 17 December 2009 в 18:51
поделиться

11 ответов

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

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

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

Примечание:

Этот ответ относится к Java-коду «Уловки», подобному указанному в вопросе, а не к плохому программированию, которое может поднять уровень циклов с O (N) до O (N ^ 2). Как правило, пишите чистый СУХИЙ код и ждите, пока операция займет слишком много времени, прежде чем исправлять ее. Вы почти никогда не достигнете этой точки, если не будете игровым дизайнером.

70
ответ дан 26 November 2019 в 20:07
поделиться

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

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

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

11
ответ дан 26 November 2019 в 20:07
поделиться

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

24
ответ дан 26 November 2019 в 20:07
поделиться

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

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

Я также практикую ваш стиль; даже если не по соображениям производительности,

2
ответ дан 26 November 2019 в 20:07
поделиться

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

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

6
ответ дан 26 November 2019 в 20:07
поделиться

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

1
ответ дан 26 November 2019 в 20:07
поделиться

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

0
ответ дан 26 November 2019 в 20:07
поделиться

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

14
ответ дан 26 November 2019 в 20:07
поделиться

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

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

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

8
ответ дан 26 November 2019 в 20:07
поделиться

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

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

0
ответ дан 26 November 2019 в 20:07
поделиться

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

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

0
ответ дан 26 November 2019 в 20:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: