for loop
有什么好处此:
for(int i = 0; i<someMethod(); i++)
{//some code
}
或:
int a = someMethod();
for(int i = 0; i<a; i++)
{//some code
}
我们只是说 someMethod()会返回一些大的内容。
第一种方法会在每个循环中执行 someMethod(),从而降低速度,第二种方法更快但是假设在应用程序中有很多类似的循环,因此声明 a 变量vill消耗更多内存。
那么更好,或者我只是在愚蠢地思考。
答案 0 :(得分:11)
第二个更好 - 假设someMethod()
没有side effects。
它实际上缓存了由someMethod()
计算的值 - 所以你不必重新计算它(假设它是一个相对广泛的操作)。
如果有(有副作用) - 两个代码段不等同 - 你应该做正确。
关于“变量a的大小” - 无论如何都不是问题,在计算之前,someMethod()
的返回值需要存储在某个中间临时变量上(甚至如果不是这种情况,一个整数的大小可以忽略不计。)
P.S。
在某些情况下,编译器/ JIT优化器可能会将第一个代码优化为第二个代码,假设当然没有副作用。
答案 1 :(得分:4)
如有疑问,请进行测试。使用分析器。测量
答案 2 :(得分:4)
假设迭代顺序不相关,并且假设您真的想要对代码进行纳米优化,那么您可以这样做:
for (int i=someMethod(); i-->0;) {
//some code
}
但是另外一个局部变量(你的a
)并不是一个负担。在实践中,这与您的第二个版本没有太大区别。
答案 3 :(得分:3)
如果你在循环后不需要这个变量,可以通过简单的方法将其隐藏在里面:
for (int count = someMethod (), i = 0; i < count; i++)
{
// some code
}
答案 4 :(得分:2)
这实际上取决于生成someMethod()的输出所需的时间。内存使用量也是一样的,因为someMethod()首先必须生成输出然后存储它。第二种方法保护你的cpu从每个循环计算相同的输出,它不应该占用更多的内存。所以第二个更好。
答案 5 :(得分:2)
我不认为变量a的内存消耗是一个问题,因为它是一个int并且在64位机器上需要192位。所以我更喜欢第二种选择,因为它的执行效率更高。
答案 6 :(得分:1)
关于循环优化的最重要部分是允许JVM展开循环。要在第一个版本中执行此操作,必须能够内联对someMethod()
的调用。内联有一些预算,可能会在某些时候被破坏。如果someMethod()足够长,JVM可能会认为它不想内联。
第二个变体对JIT编译器更有帮助,并且可能更好。
我放下循环的方法是:
for (int i=0, max=someMethod(); i<max; i++){...}
max
不会污染代码,您可以确保多次调用someMethod()及其紧凑(单线程)没有副作用
答案 7 :(得分:0)
如果你需要优化它,那么这是干净/显而易见的方法:
int a = someMethod();
for (int i = 0; i < a; i++) {
//some code
}
@dystroy建议的替代版本
for (int i=someMethod(); i-->0;) {
//some code
}
......有三个问题。
他在相反的方向迭代。
该迭代是非惯用的,因此可读性较差。特别是如果你忽略了Java风格指南,并且没有把空格放在你应该的位置。
没有证据表明代码实际上会比更惯用的版本更快......特别是一旦JIT编译器对它们进行了优化。 (即使可读性较低的版本更快,差异也可能微不足道。)
另一方面,如果someMethod()
价格昂贵(如您所假设的那样),那么“提升”通话以便只进行一次,这可能是值得的。
答案 8 :(得分:0)
我对它有些困惑,并且对其中的10,000,000个整数进行了完整性测试。差异超过2秒,而后者更快:
int a = someMethod();
for(int i = 0; i<a; i++)
{//some code
}
我在Java 8(MacBook Pro,2.2 GHz Intel Core i7)上的结果是:
使用列表对象: 开始于1565772380899, 结束于1565772381632
“ for”表达式中的调用列表: 开始于1565772381633, 结束于1565772384888