Java for循环性能问题

22

考虑以下示例:

public static void main(final String[] args) {
    final List<String> myList = Arrays.asList("A", "B", "C", "D");
    final long start = System.currentTimeMillis();
    for (int i = 1000000; i > myList.size(); i--) {
        System.out.println("Hello");
    }
    final long stop = System.currentTimeMillis();
    System.out.println("Finish: " + (stop - start));
}

public static void main(final String[] args) {
    final List<String> myList = Arrays.asList("A", "B", "C", "D");
    final long start = System.currentTimeMillis();
    final int size = myList.size();
    for (int i = 1000000; i > size; i--) {
        System.out.println("Hello");
    }
    final long stop = System.currentTimeMillis();
    System.out.println("Finish: " + (stop - start));
}

这样做会有什么区别吗?在我的机器上第二个似乎执行得更快,但我不知道它是否真的准确。编译器会优化这段代码吗?如果循环条件是一个不可变对象(例如字符串数组),我可以想象他会这样做。


1
如果你想要测量经过的时间(并且希望它准确),你应该使用System.nanoTime()。顺便说一句。 - Pascal Thivent
会记住这个好点。 - kukudas
13个回答

0

两个版本的区别在于每次迭代少了一个方法调用,因此第二个版本应该运行得稍微快一些。不过,如果您使用即时编译器,它可能会进行优化 - 发现它在循环期间没有改变。标准的Java实现具有JIT,但并非每个Java实现都具备。


标准的Java使用即时编译器。 - Michael Myers
我想表达的是,并不是每个Java实现都这样做。已编辑。 - pajton

0

通常情况下,你需要运行两个版本来看哪一个在使用实现时更快。然而,第一个版本可能会有性能损失,因为每次迭代都需要调用size()函数,而函数调用比直接检查变量更昂贵。但是,根据你的代码和编译器的优化情况,这个函数调用可能会被优化掉,所以你需要进行测试。

然而,正如Pindatjuh所指出的那样,当你要遍历整个集合时,最好使用foreach循环。这应该让编译器更好地优化代码,并且更少出错。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接