java - 检查对象是否为null的最快方法

j2e*_*nue 1 java optimization performance

有人告诉我这样做的速度更快

if(null == object) 
Run Code Online (Sandbox Code Playgroud)

这样做

if(object == null)
Run Code Online (Sandbox Code Playgroud)

我认为没有区别.请确认效率/性能是否相同.

注意......我的朋友已经进行了性能测试,以证明第一个稍快一点.

更新为什么有些人这样做:假设您不小心使用"="而不是预期的等式检查(例如"==")进行分配,如果您首先使用null,则第一个将给出编译器错误.如此重要,它更好.

ACV*_*ACV 11

我将基于@James答案:

public class TestNull {
   public void left(String s) {
       if (s == null);
   }
   public void right(String s) {
       if (null == s);
   }
}
Run Code Online (Sandbox Code Playgroud)

字节码:

public class TestNull {
  ....
  public void left(java.lang.String);
    Code:
       0: aload_1       
       1: ifnonnull     4
       4: return        

  public void right(java.lang.String);
     Code:
       0: aconst_null   
       1: aload_1       
       2: if_acmpne     5
       5: return        
}
Run Code Online (Sandbox Code Playgroud)

首先更快(当null在右侧时),因为java有一个字节码命令ifnonnull,该命令将加载的变量与null进行比较。

第二个比较慢,因为正在使用另一个命令:if_acmpne它会比较aconst_null它认为是常量的负载。

显然if_acmpneifnonnull

if_acmpne将最上面的两个对象引用弹出堆栈并进行比较。如果两个对象引用不相等(即,如果它们引用不同的对象),则执行分支到地址(pc + branchoffset),其中pc是字节码中if_acmpne操作码的地址,branchoffset是一个16位带符号整数字节码中if_acmpne操作码后面的参数。如果对象引用引用相同的对象,则在下一条指令处继续执行。

ifnonnull将顶部对象引用从操作数堆栈弹出。如果对象引用不是特殊的空引用,则执行分支到地址(pc + branchoffset),其中pc是字节码中ifnonnull操作码的地址,branchoffset是16位有符号整数参数,紧随ifnonnull操作码之后。字节码。如果堆栈上的对象引用为null,则在下一条指令处继续执行。

因此 if (s == null)必须更快(与问题中所述的OP相反)。


Rai*_*olt 6

我写了一个程序来测试这个.它只是重复调用两种方法.这些方法的唯一内容是我们要测试性能的两个比较.

public class StackOverflow {
    public static void main(String[] args) {
        String s = "";
        while (true) {
            a(s);
            b(s);
        }
    }
    private static void a(String s) {
        if (s == null);
    }
    private static void b(String s) {
        if (null == s);
    }
}
Run Code Online (Sandbox Code Playgroud)

我将一个分析器附加到我的程序中.以下是执行70秒后的结果:

在此输入图像描述

如您所见,CPU时间轻了近四倍a().这表明比较s == null确实比null == s.