Which is faster, try catch or if-else in java (WRT performance)

前端 未结 12 1929
暖寄归人
暖寄归人 2020-12-05 02:22

Which one is faster:

Either this

try {
  n.foo();
} 
catch(NullPointerException ex) {
}

or

if (n != null) n.foo();         


        
相关标签:
12条回答
  • 2020-12-05 02:50

    The if construct is faster. The condition can be easily translated to machine code (processor instructions).

    The alternative (try-catch) requires creating a NullPointerException object.

    0 讨论(0)
  • 2020-12-05 02:53

    It's not a question of which is faster, rather one of correctness.

    An exception is for circumstances which are exactly that, exceptional.

    If it is possible for n to be null as part of normal business logic, then use an if..else, else throw an exception.

    0 讨论(0)
  • 2020-12-05 02:54
    if (n != null) n.foo();
    

    is faster.

    0 讨论(0)
  • 2020-12-05 02:56

    Beside the good answers (use exceptions for exceptional cases) I see that you're basically trying to avoid the null checks everywhere. Java 7 will have a "null safe" operator that will return null when n?.foo() is called instead of throwing a NPE. That's borrowed from the Groovy language. There's also a trend to avoid using null altogether in one's code except when really needed (ie: dealing with libraries). See this other answer for more discussion on this. Avoiding != null statements

    0 讨论(0)
  • 2020-12-05 03:00

    I notice I'm not the only one reading the Java Specialist's Newsletter :)

    Apart from the fact that there's a semantic difference (the NPE isn't necessarily caused by dereferencing n, it might have been thrown by some error in foo()), and a readability issue (the try/catch is more confusing to a reader than the if), they should be about equally fast in the case when n != null (with the if/else version having a slight advantage), but when n == null if/else is a lot faster. Why?

    1. When n == null, the VM must create a new exception object and fill in its stack trace. The stack trace info is really expensive to acquire, so here the try/catch version is far more expensive.
    2. Some believe that conditional statements are slower because they prevent instruction pipelining, and by avoiding the explicit if they think they got away cheap when n != null. The thing is, however, that the VM will do an implicit null check when dereferencing... that is, unless the JIT can determine that n must be non-null, which it can in the if/else version. This means that the if/else and try/catch versions should be perform approximately the same. But...
    3. ... try/catch clauses can interfere with how the JIT can inline method calls, which means that it might not be able to optimize the try/catch version as well as the if/else.
    0 讨论(0)
  • 2020-12-05 03:00

    It is usually expensive to handle exceptions. The VM Spec might give you some insight into how much, but in the above case if (n != null) n.foo(); is faster.

    Although I agree with Mitch Wheat regarding the real question is correctness.

    @Mitch Wheat - In his defense this is a pretty contrived example. :)

    0 讨论(0)
提交回复
热议问题