【问题标题】:Which for loop header performs better?哪个 for 循环头执行得更好?
【发布时间】:2015-02-13 18:36:55
【问题描述】:

我在 Android 文档中经常看到以下内容:

int n = getCount();

for (int i = 0; i < n; i ++) {
    // do somthing
}

但我习惯于看和做:

for (int i = 0; i < getCount(); i ++) {
    // do somthing
}

我很好奇一个是否比另一个更有效率?在这两种情况下究竟发生了什么?第二种方式调用getCount()时,计算机是不是还要分配另一个变量?还是仅仅是代码清洁度或偏好的问题?

【问题讨论】:

标签: java for-loop compiler-optimization


【解决方案1】:

第一个比另一个更有效。

在第一种情况下,您只调用一次 getCount,而在第二种情况下,您为每个条件检查调用 getCount,这增加了循环的执行时间。

【讨论】:

  • 你能解释一下吗?在第二种情况下它不会调用 getCount() n 次吗?
  • @Sumedh 这可能无关紧要。我敢打赌,如果你对两者进行基准测试,两者之间的差异将微不足道甚至不存在。
  • 既然 OP 已经澄清 getSize() 是他的意思而不是 getCount(),是的,差异非常微不足道。但是如果 getCount() 或任何方法,有是一个复杂的,会有相当大的差异。
【解决方案2】:

问题不在于性能,认为第二个可能会慢一些,因为

public class stuff {
    static int getCount() {
        System.out.println("get count");
        return 5;
    }
    public static void main(String[] args) {
        for (int i = 0; i < getCount(); i ++) {
            System.out.println("loop " + i);
        }
    }

}

有输出

get count
loop 0
get count
loop 1
get count
loop 2
get count
loop 3
get count
loop 4
get count

你看到循环中的 getCount 被执行了多次吗?为什么这不是问题?你如何比较不同事物的表现?如果行为无关紧要,您可以将nopthemostcomplexComputionInThe 世界进行比较。

【讨论】:

  • 我想一个更好的例子是array.length 而不是getCount()
  • @tambykojak attayList.size() 一直困扰着我,直到 Java 1.5 引入了 foreach
【解决方案3】:

这是JDK1.6.0_21的javac编译器为这两种情况生成的:

第一种情况:

int n = getCount();

for (int i = 0; i < n; i ++) {
    // do something
}

编译后的字节码:

invokestatic example/Test/getCount()I
istore_1
iconst_0
istore_2
goto 10
... // whatever code in the loop body
iinc 2 1
iload_2
iload_1
if_icmplt 6
return

第二种情况:

for (int i = 0; i < getCount(); i ++) {
    // do something
}

编译后的字节码:

iconst_0
istore_1
goto 8
... // whatever code in the loop body
iinc 1 1
iload_1
invokestatic example/Test/getCount()I
if_icmplt 4
return

结果代码看起来可能不同,但取决于getCount(),运行时可能会优化执行。一般来说,第一个代码似乎更高效,尤其是当getCount() 执行一些复杂的操作以返回其值时。

【讨论】:

  • 如果 getCount() 使用数据库查询会怎样?然后,您可能会连续处理 50 个数据库查询,而不是 1 个。
  • getCount() 是一个不好的例子,但它仍然有效!。
  • @Compass 实际上,通常行为可能会有所不同。更新了答案。
猜你喜欢
  • 2023-02-22
  • 1970-01-01
  • 2012-06-23
  • 2014-10-14
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
  • 2012-08-12
  • 2014-04-05
相关资源
最近更新 更多