Skip to content
Home » Should You Worry About Performance When Using java.util.Optional?

Should You Worry About Performance When Using java.util.Optional?

man with hand on temple looking at laptop

⚠️ DISCLAIMER: This article doesn’t provide any empirical data about the performance of Optional. If you’re looking for empirical data, there’s a nice article that provides that.

A few days ago I did a post on LinkedIn talking about the Optional class. One comment was an excellent question:

Could the use of Optional lead to performance degradation?

The answer is: Yes, it can. But should you worry?

The Benefits of Using Optional

The Optional class makes the developer’s life easier. It:

  • Increases the code readability
  • Reduces the number of conditions in our code
  • Is less error-prone

But this comes with a price. Let’s see how some of the principal methods of the Optional class are implemented.

How is the Optional Class Implemented?

Here you have some of the main methods of Optional class:

    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

    public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

    public T orElse(T other) {
        return value != null ? value : other;
    }

    public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent()) {
            return empty();
        } else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }   

Basically, it wraps the value into a new Optional object and checks if the wrapped value is null or not.

OK, checking if the value is null or not is something that you would have to do even if you were not using Optional. It might have a few checks more than you would do, but I don’t think you have to worry about this.

But you have to know that wrapping the value into a new object will increase the number of objects to be collected by GC. It means that the heap usage will increase faster, and the CPU usage will be higher (more GC events).

OK, but how higher? Again, it depends on the number of Optional objects you’re creating, on the size of your heap, and on the amount of CPU that your application uses without using Optional.

For example, let’s say that you benchmarked your application and concluded that using Optional will increase 1 percentage point on CPU usage. If your application uses an average of 50% CPU, using 51% with Optional is not a very significant overhead, right?

But, if your application consumes an average of 5% CPU, using 6% means 20% of overhead and this is quite significant.

Premature Optimization is the Root of All Evil

There’s an entire chapter (Item 67: Optimize judiciously) on the book Effective Java, from Joshua Bloch, that talks about optimization.

He starts the chapter with:

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

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.

Donald E. Knuth

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

So, unless you need a blazing fast application and have limited resources, don’t worry about performance early. Focus on writing good code, so when and if you need, it will be easy to optimize. Also, use a profiler to find the places that have more impact on the performance.

Who Will Use Your API?

That’s also a good question that you need to ask yourself. If you’re writing an internal API, you are freer to decide between using or not using it.

But if you’re writing a public API, like a framework or library, and you don’t know what kind of application is calling it, you may need to be more flexible and give the client the choice of using Optional.

You can provide two methods, one that returns Optional and one that returns null. But when creating a method that can return null, try to let it explicit. Use the annotation javax.annotation.Nullable on your methods. (JSR 305)

In The End, It’s up to You.

You are the person who can decide about using Optional. There isn’t a simple answer that fits all cases. And most of the things in software engineering are like this. It’s all about trade-offs.

So, be aware of how it works and evaluate the alternatives. Everything has a price, and you are the one that can decide to pay or not.

Do you think it’s worth paying the price of having unreadable and more error-prone code to have some performance improvement? Do you know how significant is that improving?

For most of the cases, use Optional and be happy. Optional is great!

Still have doubts? Comment here or send me a message on my social media. It will be great to help you with that.