在Java中优化for循环是否有用?

时间:2012-08-24 19:32:57

标签: java optimization for-loop

  

可能重复:
  for loop optimization

假设我们想循环遍历字符串s的字符。我会说以下代码或多或少是默认代码。

for( int i = 0; i < s.length(); i++ ) {
    doSomethingWith( s.charAt( i ) );
}

问题#1:为什么我经常看到以下内容?

final int length = s.length();
for( int i = 0; i < length; i++ ) {
    doSomethingWith( s.charAt( i ) );
}
乍一看,这似乎是合理的,因为在每次迭代时都会评估不等式。但是我希望VM能够优化它,因为字符串是不可变的。有什么想法吗?如果我们迭代一个可变结构(没有被任何其他线程引用)会怎么样?如果length()不能保证在O(1)中运行怎么办?

问题2:有些人似乎认为用++i代替i++来加速代码。他们是对的吗?这不是我所期望的,但我只是不确定。

我们都知道不要过早优化。与此同时,如果我们几乎不用任何代价就可以生成稍微快一点的代码,那么我们就不会傻了。当然有人可能会说,“优化”都会损害可读性,但在我看来,损害是如此之小以至于在某些情况下它是合理的。

我试图测量性能上的任何差异,但很难得到确定的结果。虽然这应该适用于任何特定的应用程序,但我的目标是洞察力和一般答案。

(虽然我在考虑HotSpot VM的情况下编写此内容时,考虑其他平台(如移动设备)也会很有趣。)

2 个答案:

答案 0 :(得分:5)

  

问题#1:为什么我经常看到以下内容?

第一个例子是过早优化。人们这样做的原因是他们通常不会分析他们的代码以查看真正的瓶颈所在,而只是试着猜测。

  

如果不能保证在O(1)中运行length()怎么办?

然后进行这种优化更有意义。如果您知道计算长度是一项昂贵的操作并且该值不会改变,那么计算一次并存储结果可能会提高性能。

  

问题2:有些人似乎认为用++ i代替i ++会加速代码。他们是对的吗?这不是我所期望的,但我只是不确定。

他们不对。他们的论点是i++必须创建变量的临时副本,而++i则不然。很久以前,当编译器不擅长优化时,这在C或C ++中已经成为现实。 Java不是这样。

答案 1 :(得分:3)

  乍一看,这似乎是合理的,因为在每次迭代时都会评估不等式。但是我希望VM能够优化它,因为字符串是不可变的。

编译器优化了这一点。像i < s.length();这样做很好。

  

有些人似乎认为用++ i代替i ++会加速代码。

除非你为++ i的返回值指定了一些内容,否则它不会。