Эффективность наличия логики в строке и вызов метода?
В настоящее время у меня есть несогласие с моим 2-летним профессором JAVA, что я надеюсь, что y'all может помочь решить:
Код, с которого мы начали, был следующим:
public T peek()
{
if (isEmpty())
.........
}
public boolean isEmpty()
{
return topIndex<0;
}
И она хочет, чтобы мы удалили ссылку isEmpty()
и поместили ее код непосредственно в оператор if
(т.е. изменили содержимое метода peek:
if(topIndex<0).......
), чтобы "сделать код более эффективным". Я утверждал, что: а) оптимизатор времени выполнения/компиляции, скорее всего,
isEmpty() call, b)
, даже если это не так, операции с 5-10 машинами будут незначительными почти в каждой ситуации, а в) его просто плохой стиль, потому что он делает программу менее читаемой и менее изменчивой.
Итак, я думаю, мой вопрос:
Есть ли какая-либо эффективность выполнения, полученная логикой inlineing, а не просто вызовом метода?
Я пробовал простые методы профилирования (так называемый длинный цикл и секундомер), но тесты были неубедительными.
ИЗМЕНИТЬ:
Спасибо всем за ответы! Я ценю, что вы все тратите время. Кроме того, я ценю тех из вас, кто прокомментировал прагматизм спорить с моим профессором и особенно делал это без данных. @Mike Dunlavey Я ценю ваше понимание как бывшего профессора и ваш совет относительно соответствующей последовательности кодирования. @ya_pulser Я особенно ценю советы и ссылки для профилирования, на которые вы потратили время, чтобы поделиться.
Ответы
Ответ 1
Вы правы в своих предположениях о поведении Java-кода, но вы не владеете своим профессором, рассуждая без данных:). Рассуждение без данных бессмысленно, докажите свои предположения с помощью измерений и графиков.
Вы можете использовать JMH (http://openjdk.java.net/projects/code-tools/jmh/), чтобы создать небольшой контрольный показатель и измерить разницу между:
- в руке (удалить метод isEmpty и поместить код в место вызова)
- inlined by java jit compiler (hotspot после вызовов 100k (?) - см. вывод компиляции jit print)
- отключена встроенная функция hotspot
Пожалуйста, прочитайте http://www.oracle.com/technetwork/java/whitepaper-135217.html#method
Полезными параметрами могут быть:
- -Djava.compiler = NONE
- -XX: + PrintCompilation
Плюс каждая версия jdk имеет собственный набор параметров для управления jit.
Если вы создадите какой-то набор графических изображений в качестве результатов ваших исследований и вежливо представите их профессору - я думаю, это принесет вам пользу в будущем.
Я думаю, что https://stackoverflow.com/users/2613885/aleksey-shipilev может помочь с вопросами, связанными с jmh.
BTW: У меня был большой успех, когда я вложил множество методов в один огромный цикл кода, чтобы достичь максимальной скорости для обычной программы backpropagation для нейронной сети, потому что java (был?) слишком ленив для встроенных методов методами с методами. Это было непостижимо и быстро: (.
Ответ 2
Грустно...
Я согласен с вашими интуициями об этом, особенно "5-10 машинных операций были бы незначительными практически в каждой ситуации".
Я был профессором C.S. давным-давно.
С одной стороны, профессорам нужен все слабину, которую вы можете им дать.
Обучение очень требовательно. У тебя плохой день.
Если вы появляетесь в классе, и вы не полностью подготовлены, вам предстоит грубая поездка.
Если вы дадите тест в пятницу и не получите оценки в понедельник, студенты скажут: "Но у вас были все выходные!"
Вы можете получить удовлетворение от изучения ваших учеников, но вы сами не многому научитесь, кроме как научить.
С другой стороны, у немногих профессоров много практического опыта работы с реальным программным обеспечением.
Поэтому их мнения, как правило, основаны на различных догматических убеждениях, а не на твердом прагматизме.
Производительность - прекрасный пример этого.
Они, как правило, говорят: "Не делайте X. Сделайте Y, потому что он работает лучше". который полностью упускает из виду проблемы с производительностью - вам приходится заниматься фракциями, а не абсолютами. Все зависит от того, что еще происходит.
Способ приблизиться к производительности, так как кто-то сказал: "Сначала сделайте это правильно, а затем сделайте это быстро".
И способ, которым вы делаете это быстро, - это не заглядывать в код (и задаваться вопросом "должен ли я это делать, или я должен это делать" ), но запустив его и давая ему рассказать вам, как он проводит время.
Основная идея профилирования - это то, как вы это делаете.
Теперь есть такая вещь, как плохое профилирование и хорошее профилирование, как объясняется во втором ответе здесь (и обычно, когда преподаватели учат профилированию, они учат плохой вид), но это путь.
Ответ 3
Как вы говорите, разница будет небольшой, и в большинстве случаев читаемость должна быть более приоритетной. В этом случае, хотя, поскольку дополнительный метод состоит из одной строки, я не уверен, что это добавляет какую-либо реальную удобочитаемость, если вы не вызываете тот же метод из другого места.
Тем не менее, помните, что цель вашего лектора - помочь вам научиться информатике, и это другой приоритет, чем написание производственного кода. В частности, она не хочет, чтобы вы оставляли оптимизацию для автоматизированных инструментов, поскольку это не помогает вашему обучению.
Кроме того, просто практическое замечание - в школе и в профессиональном развитии мы все должны придерживаться стандартов кодирования, с которыми мы лично не согласны. Это важный навык, и он действительно необходим для работы в команде, даже если он работает.
Ответ 4
Вызов isEmpty
является идиоматичным и красиво читаемым.
Ручная инкрустация, которая будет представлять собой микро-оптимизацию,
что-то лучшее в критических ситуациях,
и после того, как узкое место было подтверждено путем бенчмаркинга в предполагаемой производственной среде.
Есть ли реальная производительность в ручном встраивании?
Теоретически да, и, возможно, то, что лекция хотела подчеркнуть.
На практике,
Я не думаю, что вы найдете абсолютный ответ.
Поведение автоматического вложения может быть зависимым от реализации.
Также имейте в виду, что результаты тестов будут зависеть от реализации JVM, версии, платформы.
И по этой причине,
такая оптимизация может быть полезна в редких экстремальных ситуациях,
и в целом вредно переносимости и ремонтопригодности.
По той же логике, если мы введем все методы,
устраняя все косвенные действия за счет дублирования больших блоков кода?
Точно нет.
Там, где вы рисуете линию точно между разложением и встраиванием, может также зависеть от личного вкуса,
в некоторой степени.
Ответ 5
Другим видом данных, на который можно обратить внимание, может быть код, который генерируется. См. Параметр -XX:+PrintAssembly
и друзей. Подробнее см. Как просмотреть JIT-скомпилированный код в JVM?.
Я уверен, что в этом конкретном случае Hotspot JVM будет включать вызов isEmpty
и не будет никакой разницы в производительности.