在Java中的for循环中,++我真的比i ++快吗?

Bin*_*bik 33 java performance loops premature-optimization

在java中,我通常会像以下一样进行for循环:

for (int i = 0; i < max; i++) {
   something
}
Run Code Online (Sandbox Code Playgroud)

但是最近有一位同事打字了:

for (int i = 0; i < max; ++i) {
   something
}
Run Code Online (Sandbox Code Playgroud)

他说后者会更快.真的吗?

Mar*_*ers 57

不,这不是真的.您可以通过为每个循环计时大量迭代来测量性能,但我相当确定它们是相同的.

神话来自C,其中++i被认为i++比前者更快,因为前者可以通过增加然后返回来实现.后者可以通过将i的值复制到临时变量,递增i,然后返回临时变量来实现.第一个版本不需要制作临时副本,因此很多人认为它更快.但是,如果表达式用作语句,现代C编译器可以优化临时副本,以便在实践中没有区别.

  • 现代编译器的确会优化这一点,但如果你使用的是C++,和我是一个对象(比如,一个迭代符),而这些运营商不在线,我++会比我快++. (12认同)

gsi*_*011 39

这个问题需要一些Java字节码.请考虑以下代码:

public class PostPre {
    public static void main(String args[]) {
        int n = 5;
        loop1(n);
        loop2(n);
    }

    public static void loop1(int n) {
        for (int i = 0; i < n; i++) {}
    }

    public static void loop2(int n) {
        for (int i = 0; i < n; ++i) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

现在编译并反汇编它:

$ javac PostPre.java; javap -c PostPre.class 
Compiled from "PostPre.java"
public class PostPre {
  public PostPre();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: iconst_5      
       1: istore_1      
       2: iload_1       
       3: invokestatic  #2                  // Method loop1:(I)V
       6: iload_1       
       7: invokestatic  #3                  // Method loop2:(I)V
      10: return        

  public static void loop1(int);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: iload_0       
       4: if_icmpge     13
       7: iinc          1, 1
      10: goto          2
      13: return        

  public static void loop2(int);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: iload_0       
       4: if_icmpge     13
       7: iinc          1, 1
      10: goto          2
      13: return        
}
Run Code Online (Sandbox Code Playgroud)

loop1()loop2()具有相同的字节代码.


Car*_*rum 9

对于任何合理的优化器,它们将完全相同.如果您不确定,请查看输出字节码或对其进行分析.


biz*_*lop 5

即使它是,我非常怀疑,你的同事应该有更好的事情来花时间学习而不是如何优化循环表达式.

  • 看,妈!如果我只使用字母表前半部分的字母来表示变量名,我的程序运行得更快!到重构机器! (15认同)
  • 可怕的是,在许多编译器中,较短的变量名称使用较少的内存.我们可以整天痴迷于微小的黑客攻击,但我的处理器没有任何理由没有7.3亿个晶体管. (3认同)