Если ответ не о семантике, а о производительности на уровне машины после того, как ИК оптимизирован, переведен в машинные инструкции, я бы сказал: «нет, если только не измерено и не доказано иное».
Это очень маловероятно, что будет разница в производительности после всех оптимизаций между f(++i)
и f(i+1)
, предполагая, что ваш код таким образом, что вы можете рассматривать их в качестве альтернативы (если предположить, что состояние i
перестает стать актуальным после того, как вызов функции).
Это всего лишь базовое аппаратное и компиляторное оформление, стоимость инструкций для памяти, уже сохраненных в регистре, простота оптимизации этого кода для одного и того же машинного кода даже в полуграмотном компиляторе (и я думаю, что Java JIT, по крайней мере, был бы таким). Это очень простой характер компилятора, который распознает ненужные побочные эффекты и устраняет их прямо (на самом деле одна из причин, по которым искусственные тесты на микроуровне могут вводить в заблуждение, если они не будут написаны очень тщательно, таким образом, чтобы оптимизатор не пропускал определенный код прямо). Среди самых простых побочных эффектов для исключения - такой случай, когда мы увеличиваем переменную, i
, но не в зависимости от изменения состояния впоследствии.
Похоже, что это не повлияет на производительность. Конечно, конечный способ - посмотреть на конечный итоговый машинный код (а не на байт-код IR, а на фактический конечный машинный код) или измерить и профилировать его. Но я был бы в шоке, если бы был быстрее, чем другой, и это заставило бы меня подумать, что компилятор делает довольно плохую работу в выборе команд или распределении регистров.
Это, если кто-то действительно был (удаленный случай) быстрее, чем другой, я думаю, что у вас есть это в обратном направлении. ++i
, вероятно, потребует меньше работы, поскольку он может просто увеличить значение в регистре. ++i
является унарной операцией на одном операнде, и это хорошо работает с реестрами, которые изменяются. i + 1
- это выражение, которое требует, чтобы i
считалось неизменным и требовало бы второго регистра (но только в действительно ужасном виде сценария компиляции игрушек, который ничего не оптимизировал, хотя в этом случае мы также компилируем это выражение в контекст вызова функции и должны учитывать такие вещи, как утечки стека, поэтому даже игрушечный компилятор может сделать их несколько эквивалентными).
Я предлагаю вам использовать http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html два простых класса (или класс с двумя методами), каждый с одним из в двух подходах вы лучше поймете все это, а не прочитаете здесь ответ. ^^ –
Компилятор JIT действительно мог бы сделать такую оптимизацию на том основании, что 'i' мертв после приращения. Действительно ли это делает такую оптимизацию, это еще один вопрос. Компилятор Java-to-bytecode не оптимизирует это для вас; приращение будет в байт-коде. Это на 100% до компилятора JIT для оптимизации. –
* «Я знаю, что результат тот же» * Зависит от кода. Если вы получаете доступ к «i» более одного раза, результат не совпадает. – Tom