Which is faster in Java, and why?
try {
object.doSomething()
} catch (NullPointerException e) {
if开发者_开发百科 (object == null) {
object = new .....;
object.doSomething();
} else throw e;
}
or
if (object == null) {
object = new .....;
}
object.doSomething();
and why?
The code would be called often, and object
is only null
the first time it's called, so don't take the cost of the thrown NPE
into account (it only happens once).
P.S. I know the second is better because of simplicity, readability, etc, and I'd surely go for that in real software. I know all about the evil of premature optimization, no need to mention it. I'm merely curious about these little details.
You should absolutely use the latter way, not because it's faster, but because it's more idiomatic. Exceptions should not be used for control flow in your java programs.
this is purely anecdotal, but all the microbenchmarking I have ever done has shown that using exceptions for control flow won't be as performant as conditionals, although it's probably impossible to support this as a generalization and the JVM is very good at optimizing around things like this anyways, so YMMV.
Forget about speed - look at the size of the code in the first snippet versus the second.
Is the simpler option the best one? Easiest to read, takes up less space, etc. You should strive for code simplicity first, and then worry about speed once you've measured something as slow.
Besides, think about what the runtime needs to do in order to determine that it needs to throw a NullPointerException
- it has to check if the current reference is null
. So even without measuring, it would logically make sense that performing the check yourself is simpler, rather than leaving it up to the JRE to make the check and create a NullPointerException
and unwind the stack.
Regardless of speed, the first way is not good programming practice. For example, what if object
was not null but object.doSomething()
resulted in the NullPointerException
?
This is one reason why you should not use exceptions to control program flow!
To answer your question, version 1 is much slower when it explodes because creating Exceptions is quite expensive, but it is not faster than version 2 because the JVM must do the null check itself anyway so you're not saving anytime. The compiler is likely to optimize the code so it's no faster anyway.
Also Exceptions should be reserved for the exceptional. Initial state of null is not exceptional.
Use the lazy initialization pattern:
SomeClass getIt() {
if (it == null)
it = new SomeClass();
return it;
}
...
getIt().someMethod();
Check the The Java Specialists' Newsletter - Issue 187 Cost of Causing Exceptions for some interesting internal details.
a thrown exception (first example) is nearly always slower than normal control flow code (second example)
that aside the second is much cleaner and easier to understand
I'm going to say the second solution is faster. Not because I'm an expert on the JIT or VM but because it makes sense that a single branch-if-equal assembly-level routine is faster than looking up the object in memory, determining that it is null (the same test, I assume), throwing an exception and possibly mucking up the stack.
精彩评论