Since JDK 7 I've been happily using the method it introduced to reject null
values which are passed to a method which cannot accept them:
private void someMethod(SomeType pointer, SomeType anotherPointer) {
Objects.requireNonNull(pointer, "pointer cannot be null!");
Objects.requireNonNull(anotherPointer, "anotherPointer cannot be null!");
// Rest of method
}
I think this method makes for very tidy code which is easy to read, and I'm trying to encourage colleagues to use it. But one (particularly knowledgeable) colleague is resistant, and says that the old way is more efficient:
private void someMethod(SomeType pointer, SomeType anotherPointer) {
if (pointer == null) {
throw new NullPointerException("pointer cannot be null!");
}
if (anotherPointer == null) {
throw new NullPointerException("anotherPointer cannot be null!");
}
// Rest of method
}
He says that calling requireNonNull
involves placing another method on the JVM call stack and will result in worse performance than a simple == null
check.
So my question: is there any evidence of a performance penalty being incurred by using the Objects.requireNonNull
methods?
requireNonNull(bar, "bar must not be null"); is ok in constructors, but potentially dangerous in other methods if two or more variables are set in the same method.
RequireNonNull(Object)Checks that the specified object reference is not null . C# Copy. [Android.Runtime.Register("requireNonNull", "(Ljava/lang/Object;)Ljava/lang/Object;", "")] [Java.Interop.JavaTypeParameters(new System.String[] { "T" })] public static Java.Lang.
The nonNull method is a static method of the Objects class in Java that checks whether the input object reference supplied to it is non-null or not. If the passed object is non-null, then the method returns true. If the passed object is null , then the method returns false.
Let's look at the implementation of requireNonNull
in Oracle's JDK:
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
So that's very simple. The JVM (Oracle's, anyway) includes an optimizing two-stage just-in-time compiler to convert bytecode to machine code. It will inline trivial methods like this if it can get better performance that way.
So no, not likely to be slower, not in any meaningful way, not anywhere that would matter.
So my question: is there any evidence of a performance penalty being incurred by using the
Objects.requireNonNull
methods?
The only evidence that would matter would be performance measurements of your codebase, or of code designed to be highly representative of it. You can test this with any decent performance testing tool, but unless your colleague can point to a real-world example of a performance problem in your codebase related to this method (rather than a synthetic benchmark), I'd tend to assume you and he/she have bigger fish to fry.
As a bit of an aside, I noticed your sample method is a private
method. So only code your team is writing calls it directly. In those situations, you might look at whether you have a use case for assertions rather than runtime checks. Assertions have the advantage of not executing in "released" code at all, and thus being faster than either alternative in your question. Obviously there are places you need runtime checks, but those are usually at gatekeeping points, public methods and such. Just FWIW.
Formally speaking, your colleague is right:
If someMethod()
or corresponding trace is not hot enough, the byte code is interpreted, and extra stack frame is created
If someMethod()
is called on 9-th level of depth from hot spot, the requireNonNull()
calls shouldn't be inlined because of MaxInlineLevel
JVM Option
If the method is not inlined for any of the above reasons, argument by T.J. Crowder comes into play, if you use concatenation for producing error message
Even if requireNonNull()
is inlined, JVM wastes time and space for performing this.
On the other hand, there is FreqInlineSize
JVM option, which prohibits inlining too big (in bytecodes) methods. The method's bytecodes is counted by themselves, without accounting size of methods, called within this method. Thus, extracting pieces of code into independent methods could be useful sometimes, in the example with requireNonNull()
this extraction is made for you already.
If you want evidence ... then the way to get it is to write a micro-benchmark.
(I recommend looking at the Calliper project first! Or JMH ... per Boris's recommendation. Either way, don't try and write a micro-benchmark from scratch. There are too many ways to get it wrong.)
However, you can tell your colleague two things:
The JIT compiler does a good job of inlining small method calls, and it is likely that this will happen in this case.
If it didn't inline the call, the chances are that the difference in performance would only be a 3 to 5 instructions, and it is highly unlikely that it would make a significant difference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With