Java API中的循环计数器

nam*_*ked 3 java performance loops

所有,

在浏览Java API中的一些文件时,我注意到许多实例,其中循环计数器正在递减而不是递增.即在String类中的in forwhile循环.虽然这可能是微不足道的,但减少计数器而不是增加是否有任何意义?

And*_*s_D 7

我用eclipse 3.6(java 6)编译了两个简单的循环,并查看字节代码是否有一些差异.这是代码:

for(int i = 2; i >= 0; i--){}
for(int i = 0; i <= 2; i++){}
Run Code Online (Sandbox Code Playgroud)

这是字节码:

// 1st for loop - decrement 2 -> 0
 0 iconst_2
 1 istore_1      // i:=2
 2 goto 8
 5 inc 1 -1      // i+=(-1)
 8 iload_1
 9 ifge 5        // if (i >= 0) goto 5

// 2nd for loop - increment 0 -> 2
12 iconst_0 
13 istore_1      // i:=0
14 goto 20
17 inc 1 1       // i+=1
20 iload_1
21 iconst 2
22 if_icmple 17  // if (i <= 2) goto 17
Run Code Online (Sandbox Code Playgroud)

递增/递减操作应该没有区别,它是+1或者+(-1).这个典型(!)示例的主要区别在于,在第一个示例中,我们将其与0(ifge i)进行比较,在第二个示例中,我们将其与值(if_icmple i 2)进行比较.并且每次迭代都会完成同样的事情.因此,如果有任何(轻微的)性能增益,我认为这是因为与0进行比较然后与其他值进行比较的成本更低.所以我猜这不是增加/减少,而是产生差异,而是停止标准.

因此,如果您需要在源代码级别上进行一些微优化,请尝试以与零比较的方式编写循环,否则请尽可能保持可读性(并且更容易理解递增):

 for (int i =  0; i <= 2; i++) {}  // readable
 for (int i = -2; i <= 0; i++) {}  // micro-optimized and "faster" (hopefully)
Run Code Online (Sandbox Code Playgroud)

加成

昨天我做了一个非常基本的测试 - 刚刚创建了一个2000x2000阵列,并根据单元索引的计算填充了单元格,从0->1999行和单元格开始计数,再次从后面开始计算1999->0.我并不感到惊讶,两个场景都有类似的性能(在我的机器上185 ... 210毫秒).

所以是的,字节代码级别(eclipse 3.6)存在差异,但是,嘿,我们现在在2010年,现在似乎没有显着差异.再次,使用斯蒂芬斯的话,"不要浪费你的时间"这种优化.保持代码可读和易懂.