当99%的时间对象不为空时,空检查与try/catch

Jag*_*ags 8 java

通常我更喜欢空检查.但在目前的情况下,我知道大部分时间我的if条件都会通过,并且很少有合法的场景,其中object可能为null.

此外,负载是巨大的(约500万次电话/小时)

现在我试图从性能角度找出哪种方式更好.已经检查过java中的try/catch vs null检查,但我的情况是唯一的.

还检查哪个更快,在java中尝试catch或if-else(WRT性能)但是这个和上面的都是在通用上下文中,其中通过/失败比率的知识不可用.

public void process(Job job) {
    //... some code which processes job

    SubJob subJob = job.getSubJob();
    if(subJob != null) {  // 99% of the time this will pass
        //.. do something
    }               
}
Run Code Online (Sandbox Code Playgroud)

尝试/捕捉版本

public void process(Job job) {
    //... some code which processes job

    SubJob subJob = job.getSubJob();
    try {
        //.. do something  
    }catch(NullPointerException e) { //This may occure only 1% of the time. 
        //...   
    }               
}
Run Code Online (Sandbox Code Playgroud)

更新:

获胜者是空检查.在Try/catch中,内部JVM将执行空检查并且无论如何都会抛出NPE,并且在JVM中创建异常处理(堆栈等的创建)将是开销.另外,根据另一个答案,现代CPU足够聪明,可以通过良好的预测来处理这些情况,在我的独特案例中,这些预测总是有利于.

我还编写了程序(在我的名字下面发布),结果清楚地表明我的AMD处理器上的空检查更好.

谢谢大家指导我.

wer*_*ero 7

TL; DR:如果你没有在代码中进行空检查,那么运行时无论如何都会为你插入一个.空检查几乎总是没有成本.


您需要从HotSpot或优化JIT编译器的角度来查看此问题:

在对象变量上调用方法时

someObject.callMethod()
Run Code Online (Sandbox Code Playgroud)

然后,如果变量为null(Pseudo ASM),运行时需要抛出NPE:

check someObject ref not null else throw NPE
invoke 'callMethod' on 'someObject' 
Run Code Online (Sandbox Code Playgroud)

现在有时运行时可以确定变量不为null.此分析称为空检查消除.

-- no need: check someObject ref not null else throw NPE
invoke 'callMethod' on 'someObject' 
Run Code Online (Sandbox Code Playgroud)

线索是你检查Java源代码

if (someObject != null)
Run Code Online (Sandbox Code Playgroud)

足以向运行时证明变量不为null.

理由:

总是喜欢空检查捕捉NPE.如果不进行空检查,则运行时将为您插入.