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