STOP using exceptions for flow control

Exceptions may be causing unnecessary performance impact on your application — if you use them for flow control.

How It Works

By default, when an exception is instantiated, it is necessary to capture the execution stack trace.

Capturing the stack trace involves inspecting the current thread and recording information about its state, such as which methods were called, method names, and the line number where the exception occurred.

This capture process can be significant, especially if the stack is deep, consuming CPU and memory, consequently causing performance impact.

In Detail

When we throw an exception, a search begins for an error handling mechanism (try-catch).

This search can be costly, especially if the exception needs to pass through multiple layers in the stack.

Additionally, error handling mechanisms can make the flow harder to read and understand.

These mechanisms are distributed across various application layers — in most cases — requiring navigation through several classes to understand their behavior.

Tips and Tricks

  1. Avoid using exceptions for flow control. Use exceptions for unexpected conditions similar to errors.
  2. Disable stack trace capture. If you don’t use it [and your language allows], disable capturing the stack trace.
  3. Keep try-catch nearby. Handle errors in layers close to where the exception is thrown.

The Numbers

Below is a list of results obtained from testing each approach:

ScenarioExecutionsDuration
Without throwing exception100k1ms
Throwing exception, no stack100k2.4ms
Throwing exception with stack100k43.4ms
Without throwing exception10 million17ms
Throwing exception, no stack10 million72.2ms
Throwing exception with stack10 million3720ms

I strongly encourage you to run the tests yourself, modify them, and create other scenarios.

The Moral of the Story

Exceptions are a powerful tool for error handling and were not designed to be used as a flow control mechanism.

Using them this way can cause performance problems, reduce code readability, and violate principles of some programming languages.

In summary, always opt for using the flow control tools your language offers (if-else, switch, break, etc.) and use exceptions only for truly unexpected cases.

Go Deeper