Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 requireNonNull method with supplier parameter performance

Method Objects.requireNonNull with Supplier added in Java 8, but I'm not sure what's the performance improvement declared:

While this may confer a performance advantage in the non-null case, when deciding to call this method care should be taken that the costs of creating the message supplier are less than the cost of just creating the string message directly.

Method with String ignores parameter if not null:

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

I found JDK-8011800 : Add java.util.Objects.requireNonNull(T, Supplier)

In JDK 7, java.util.Objects included several methods to check for null, including one that took a message to return if a null was found. With lambdas in JDK 8, another variant to include is a requireNonNull method which takes a string supplier instead of a string. That why the cost of creating the string message can be avoided for the non-null case. Note that the lambda capture can have a nonzero cost though.

With comment indicate no performance impact:

The non-zero capture cost does worry me. I am concerned that it will frequently erase any advantage of using a Supplier. 09-04-2013

I found other questions, but not referring to (why) sending String parameter have performance costs

Is it specific for lambda expressions/stream usage?

like image 803
user7294900 Avatar asked Dec 23 '22 01:12

user7294900


1 Answers

Consider this, where generateString does a lot of stuff in order to generate a string from someParam:

Objects.requireNonNull(obj, generateString(someParam));

Arguments are evaluated eagerly in Java, which means that generateString will be evaluated before requireNonNull is called. It is therefore computed regardless of whether obj is null or not.

You can fix this problem by changing it to this:

Objects.requireNonNull(obj, () -> generateString(someParam));

In this case, generateString will only be called if obj actually was null. This is more efficient when generateString is more expensive than creating the Supplier-object.

You should just use the normal non-lambda method if your String parameter is just a literal, like:

Objects.requireNonNull(obj, "obj was null!");
like image 112
marstran Avatar answered Dec 25 '22 16:12

marstran