Будет ли выражение «число-предел» цикла for вычисляться только один раз или на каждой итерации? - PullRequest
6 голосов
/ 01 сентября 2011

Если я вызову метод в условном выражении цикла, будет ли он вызываться при каждой итерации цикла?

Например:

for( int i = 0; i <= expensiveComputation(); i++ ) {
    // Do something.
}

Буду ли я выполнять expensiveComputation() на каждомитерация?Или же результат expensiveComputation() будет храниться и использоваться на каждой итерации одновременно с инициализацией переменной цикла?

Должен ли я вместо этого перезаписать ее так:

int max = expensiveComputation();
for ( int i = 0; i <= max; i++ ) {
    // Do something.
}

Ответы [ 4 ]

9 голосов
/ 01 сентября 2011

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

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

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

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

2 голосов
/ 01 сентября 2011

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

Если вы хотите убедитесь, что не вызывается на каждой итерации, а затем используйте int max = ... версию.

Почему бы просто не проверить ее самостоятельно?

2 голосов
/ 01 сентября 2011

Второй вариант лучше, особенно если вычисление не требуется вычислять на каждой итерации

Если вы предполагаете, что ваш цикл имеет длину n, а ваши вычисления - O (n).При первом решении сложность составляет O (n 2 ) , а другое - O (2n)

1 голос
/ 01 сентября 2011

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

...