67

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?

bonapart3
  • 469
  • 7
  • 20
Bobulous
  • 12,967
  • 4
  • 37
  • 68
  • 22
    No. It is not. Your "knowledgeable" colleague is evidently not as knowledgeable as (s)he thinks. Whatever performance impact it might have is negligible and will most likely be inlined by the JIT if it detects that the method is heavily used. – Boris the Spider Apr 25 '15 at 11:40
  • 21
    The JIT will happily inline those method calls. You should recall the first rule of optimization to your old padawan: *don't*. He should be the one to prove that this method call is the cause of a significant problem before forcing everyone to produce less readable code. – JB Nizet Apr 25 '15 at 11:40
  • 11
    [OpenJDK bug 8073479](https://bugs.openjdk.java.net/browse/JDK-8073479) converted the JDK's traditional `foo.getClass()` null checks to use `Objects.requireNonNull` instead, claiming no performance degradation and sometimes an improvement. – Jeffrey Bosboom Apr 30 '15 at 00:00
  • It may sound stupid, but I think a `public Object self() { return this; }` on Object's class would be prettier. Wouldn't? – Jaumzera Jul 26 '17 at 20:42
  • 4
    http://cr.openjdk.java.net/~shade/scratch/NullChecks.java –  Apr 05 '18 at 14:30
  • 2
    [Brian Goetz commented](https://stackoverflow.com/questions/31005009/objects-requirenonnullt-obj-instead-of-null-checks-and-manually-thrown-illegal#comment50039504_31005009) in 2015 on [this Question](https://stackoverflow.com/q/31005009/642706): *… its quite possible in the future that the JVM will eventually intrinsify Objects.requireNonNull, which is another reason to prefer it.* – Basil Bourque Oct 01 '18 at 21:58

9 Answers9

82

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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Something else which is scratching at my mind: is there any cost in creating a `String` instance when calling the version of `requireNonNull` which takes an error message as a second parameter? If so, does hiding the error message inside an `if` block avoid this cost when the `== null` test is `false`? – Bobulous Apr 25 '15 at 12:08
  • 8
    @Bobulous: The string will already exist, as string literals are pre-loaded when the class file is loaded and put in the string pool. If you were doing `Objects.requireIfNull(blah, "literal" + runtimeString);`, then you'd be creating a `StringBuilder` at runtime (under the covers) to do the concatenation, even if the resulting string weren't used. That might be some overhead. But not if you're using literals or references to existing static strings. **And** never underestimate the JIT! It's fully allowed to not just inline, but *reorder*, code to avoid dead stores like that. – T.J. Crowder Apr 25 '15 at 12:19
  • 2
    @Bobulous This answer is perfectly right, just let me add, that in case you needed a dynamic message, consider using Guava's [checkNotNull with an errorMessageTemplate](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Preconditions.html#checkNotNull(T,%20java.lang.String,%20java.lang.Object...)). This eliminates the string concatenation if it's not needed (a varargs array gets created instead which is cheaper and possibly easier to eliminate by the JIT). – maaartinus Apr 26 '15 at 03:10
22

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.

leventov
  • 14,760
  • 11
  • 69
  • 98
6

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 3
    This [JMH comparison of null check methods](http://cr.openjdk.java.net/~shade/scratch/NullChecks.java) suggests that even in the case where inlining fails the `Objects.requireNonNull` method takes less than 2ns longer than the if-null code. And where the code has been inlined, there does not appear to be any significant difference between the two ways. – Bobulous Dec 09 '16 at 11:58
4

Yes, there is evidence that the difference between manual null check and Objects.requireNonNull() is negligible. OpenJDK commiter Aleksey Shipilev created benchmarking code that proves this while fixing JDK-8073479, here is his conclusion and performance numbers:

TL;DR: Fear not, my little friends, use Objects.requireNonNull.
       Stop using these obfuscating Object.getClass() checks,
       those rely on non-related intrinsic performance, potentially
       not available everywhere.

Runs are done on i5-4210U, 1.7 GHz, Linux x86_64, JDK 8u40 EA.

The explanations are derived from studying the generated code
("-prof perfasm" is your friend here), the disassembly is skipped
for brevity.

Out of box, C2 compiled:

Benchmark                  Mode  Cnt  Score   Error  Units
NullChecks.branch          avgt   25  0.588 ± 0.015  ns/op
NullChecks.objectGetClass  avgt   25  0.594 ± 0.009  ns/op
NullChecks.objectsNonNull  avgt   25  0.598 ± 0.014  ns/op

Object.getClass() is intrinsified.
Objects.requireNonNull is perfectly inlined.

where branch, objectGetClass and objectsNonNull are defined as follows:

@Benchmark
public void objectGetClass() {
    o.getClass();
}

@Benchmark
public void objectsNonNull() {
    Objects.requireNonNull(o);
}

@Benchmark
public void branch() {
    if (o == null)  {
        throw new NullPointerException();
    }
}
mrts
  • 16,697
  • 8
  • 89
  • 72
1

Your colleague is most likely wrong.

JVM is very intelligent and will most likely inline the Objects.requireNonNull(...) method. The performance is questionable but there will be definitely much more serious optimizations than this.

You should use the utility method from JDK.

Crazyjavahacking
  • 9,343
  • 2
  • 31
  • 40
1

Effective Java by Joshua Bloch

Item 67: Optimize judiciously

There are three aphorisms concerning optimization that everyone should know:

More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason—including blind stupidity.
—William A. Wulf [Wulf72]

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
—Donald E. Knuth [Knuth74]

We follow two rules in the matter of optimization:
Rule 1. Don’t do it.
Rule 2 (for experts only). Don’t do it yet—that is, not until you have a perfectly clear and unoptimized solution.
—M. A. Jackson [Jackson75]

Hulk
  • 6,399
  • 1
  • 30
  • 52
Michael G
  • 31
  • 4
  • 6
    This is good general advice, but not very good as an answer to this specific question. [Stack Overflow is not a forum](https://meta.stackexchange.com/questions/92107). – Tom Zych Aug 01 '18 at 09:19
1

Meh, No. But, yes.

No, the direct code is always better since the method stack does not need to be touched.

Yes, if the VM implementation has null-check skips or some optimized null-checks.

Meh, method stack is so light to be modified and updated (yet it will consume some time).

LSafer
  • 344
  • 3
  • 7
0

As a general rule, readability and maintainability should trump optimization.

This rule safeguards against speculative optimization from people who think they know how a compiler works even though they have never even attempted to write one and they have never had a look inside one.

Your colleague is wrong unless they prove that the performance penalty is noticeable and untenable for users.

punkstarman
  • 71
  • 1
  • 4
-4

Objects.requireNonNull is more optimised as if you this you are code reusability. Also in oracle requireNonNull si defined as

public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
} 

so its already in bytecode.

richa ojha
  • 1
  • 1
  • 3