我已经在学校告知,这是一个不好的做法,修改for loop
的指标变量:JVM选项以优化循环语句
例子:
for(int i = 0 ; i < limit ; i++){
if(something){
i+=2; //bad
}
if(something){
limit+=2; //bad
}
}
的论点是,一些编译器优化可以优化循环而不是重新计算每个循环处的索引和边界。
我在java
中做了一些测试,似乎默认情况下每次都会重新计算索引和边界。
我想知道是否有可能在JVM HotSpot
中激活这种功能?
例如优化这种循环:
for(int i = 0 ; i < foo.getLength() ; i++){ }
,而无需编写:
int length = foo.getLength()
for(int i = 0 ; i < length ; i++){ }
这只是一个例子,我很好奇,想试试,看看改进措施。
编辑
据彼得Lawrey回答为什么在这个简单的例子JVM不内联getLenght()
方法?:
public static void main(String[] args) {
Too t = new Too();
for(int j=0; j<t.getLength();j++){
}
}
class Too {
int l = 10;
public Too() {
}
public int getLength(){
//System.out.println("test");
return l;
}
}
在输出“test”中打印10次。
我认为可以很好地优化这种执行。
编辑2: 好像我犯了一个误解......
我删除println
确实探查告诉我,该方法getLength()
甚至没有在这种情况下调用一次。
您似乎误解*内联函数的作用。每个编译器优化的101个是生成的代码在功能上等同于JLS要求的行为。这意味着我们可以内联一个函数调用,但是我们不能删除一个'println()'调用。此外,你真的不应该担心这样的编译器优化 - 或者如果你这样做,你必须至少理解如何测试这种代码。 – Voo 2012-02-18 00:19:32
好吧我不知道,我很新,仍然学到很多东西。这种“进步?”知识在(我)学校没有教学,所以我试图自己理解,而且我经常犯错误:s – 2012-02-18 00:40:14
很自由,实际上仔细查看了代码 - 很快回答你的问题:JIT将内联'getLength ()'很好,独立于你是否有println()语句。如果你想要的细节我发布了下面的简短摘要;) – Voo 2012-02-18 01:09:31