如果我在循环的条件语句中调用一个方法,是否会在每次循环迭代时调用它?
例如:
for( int i = 0; i <= expensiveComputation(); i++ ) {
// Do something.
}
我会在每次迭代中执行expensiveComputation()
吗?或者,在循环变量初始化的同时,是否会在每次迭代中存储和使用expensiveComputation()
的结果?
我应该将其重新写入:
int max = expensiveComputation();
for ( int i = 0; i <= max; i++ ) {
// Do something.
}
答案 0 :(得分:9)
除非编译器/优化器确定它没有副作用并且可能将调用作为优化消除,否则将在每次迭代时调用它。
我的意思是,编译器不能盲目地存储该值,因为java中的函数与数学函数不同,不仅可以具有返回值,还可以具有将某些内容打印到某个流或改变某些全局的副作用国家等。
还有另一个原因导致编译器无法在每次迭代时省略调用。您的函数不接受任何参数的事实并不意味着它每次都必须返回相同的值。例如,它可以从流中输入一个数字并将其返回,或者它可以随机生成一个数字。
因此编译器在安全地消除调用之前需要非常小心。所以,如果功能很昂贵,你一定要预先存储它的价值。
答案 1 :(得分:2)
如果计算不需要在每次迭代时计算,则第二个选项更好
如果你假设你的循环是n长度而你的计算是O(n)。
对于第一种解决方案,复杂性是 O(n 2 ),而另一种是 O(2n)
答案 2 :(得分:2)
每次迭代都可以调用它,也可以不调用,具体取决于编译器发出的字节码。实际上每次调用它很可能会被调用。
如果您希望确保在每次迭代时都不会调用它,请使用int max = ...
版本。
为什么不自己测试呢?
答案 3 :(得分:1)
是的,您应该在这些情况下缓存结果,以确保更好的性能。