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

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 to the client the choice of using Optional or not.

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.

2 thoughts on “Should You Worry About Performance When Using java.util.Optional?”

  1. > Increases the code readability
    No. I have a code base with heavy use of optionals and it’s just awful to read. if conditions are far easier on the eye and on the mind.
    > Reduces the number of conditions in our code
    Maybe. But it increases the number expensive of calls, lambdas, wrappers and so on.
    > Is less error-prone
    No. Because it decreases code readability and effectively makes code more complex.

    1. I don’t know how heavy is the usage that you’re talking about. But I agree that an excessive use can decrease the readability. We need to be aware of the reason why Optional was created, which is to be returned by methods that can return null. Any use different from that might be a misusage. For example, you shouldn’t use Optional as an attribute or a method parameter. Also, there are cases that even being used as a return type, it might not be the best choice. For example, if 95% of the times the method will return a non-null/non-empty value, it might better not use Optional. My point is, you don’t need to use it everywhere. Use it to help you increase readability where it can be done, and don’t worry about performance too early.

Leave a Reply

Your email address will not be published. Required fields are marked *