nam*_*ked 3 java performance loops
所有,
在浏览Java API中的一些文件时,我注意到许多实例,其中循环计数器正在递减而不是递增.即在String类中的in for和while循环.虽然这可能是微不足道的,但减少计数器而不是增加是否有任何意义?
我用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年,现在似乎没有显着差异.再次,使用斯蒂芬斯的话,"不要浪费你的时间"这种优化.保持代码可读和易懂.