Complexity (or cognitive complexity) is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, our Complexity metric tells you how difficult your code will be to read and understand. Understanding and managing code complexity is crucial for several reasons:Documentation Index
Fetch the complete documentation index at: https://docs.qlty.sh/llms.txt
Use this file to discover all available pages before exploring further.
- Readability: Code that is easy to read helps developers quickly grasp the logic and intent, facilitating better collaboration and code reviews.
- Defect Prevention: Lower complexity reduces the likelihood of bugs, as straightforward code paths are less prone to errors.
- Efficiency: Developers can work more efficiently with less complex code, leading to faster development cycles and more reliable software.
Our Complexity metric powers our Code Smells for high function complexity and
high file complexity.
The Idea
A functions’s Complexity is based on a few simple principles:- Code is considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each break in the linear flow of the code
- Code is considered more complex when flow breaking structures are nested
Shorthand
Let’s say you’re writing Ruby, and you write:Ruby && conditional
&&, which contributes the method’s Complexity. If, however, you were to use the “safe navigation” operator and write:
Ruby safe navigation
Breaks in flow
When a method’s logic flows from top to bottom, it is very easy to understand. Take this JavaScript snippet for example:Simple total
Looping total
for loop changes the function so it no longer flows directly from top to bottom, but now loops in circles a few times in the middle, which contributes to Complexity for the reader. It’s a small thing, but it adds up.
Other examples of breaks in flow:
- loops
- conditionals
- catching/rescuing exceptions
- switch or case statements
- sequences of logical operators (e.g.
a || b && c || d) - recursion
- jumps to labels
Nesting
The more deeply-nested your code gets, the harder it can be to reason about. This line of Java is pretty straight-forward:If statement
Nested logic
- conditionals
- loops
- try/catch blocks
Difference from Cyclomatic Complexity
As an example of code which is easy to understand, but difficult to test, consider this PHP example:Switch/case in PHP