繁体   English   中英

Java for循环性能

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM