> ## 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.

# Complexity

Complexity (or *cognitive* complexity) is a measure of how difficult a unit of code is to intuitively understand. Unlike [Cyclomatic Complexity](https://en.wikipedia.org/wiki/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:

1. **Readability:** Code that is easy to read helps developers quickly grasp the logic and intent, facilitating better collaboration and code reviews.
2. **Defect Prevention:** Lower complexity reduces the likelihood of bugs, as straightforward code paths are less prone to errors.
3. **Efficiency:** Developers can work more efficiently with less complex code, leading to faster development cycles and more reliable software.

By identifying and addressing complex code, developers can enhance the maintainability, readability, and overall quality of their codebase.

Qlty can help you identify which files and functions are overly difficult to understand and prevent introducing them into your code.

<Tip>
  Complexity insights are provided by [Qlty CLI](/cli/quickstart) and [Qlty
  Cloud](/cloud/quickstart).
</Tip>

<Note>
  Our Complexity metric powers our [Code Smells](/code-smells) for high function complexity and
  high file complexity.
</Note>

## The Idea

A functions's Complexity is based on a few simple principles:

1. Code is considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
2. Code is considered more complex for each break in the linear flow of the code
3. Code is considered more complex when flow breaking structures are nested

Let's break those down:

### Shorthand

Let's say you're writing Ruby, and you write:

```ruby Ruby && conditional lines theme={"system"}
def destroy(post)
  if current_user && current_user.admin?
    post.destroy
  end
end
```

This uses `&&`, which contributes the method's Complexity. If, however, you were to use the "safe navigation" operator and write:

```ruby Ruby safe navigation lines theme={"system"}
def destroy(post)
  if current_user&.admin?
    post.destroy
  end
end
```

This is a bit more intuitive, and doesn't contribute to the method's Complexity.

### 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:

```javascript Simple total lines theme={"system"}
function count(a, b, c) {
    var total = 0;

    total += a;
    total += b;
    total += c;

    return total;
}
```

It flows from top to bottom with no breaks. Compare to this alternative implementation:

```javascript Looping total lines theme={"system"}
function count(a, b, c) {
    var total = 0;
    var nums = [a, b, c];

    for (var i = 0; i < nums.length; i++) {
        total += nums[i];
    }

    return total;
}
```

The `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:

```java If statement lines theme={"system"}
if (env.debugMode()) {
  System.out.println("Hello, world!");
}
```

But when you're nested within multiple layers of conditionals or loops, a simple conditional isn't just a simple conditional, and leads to a greater Complexity.

Here's the same conditional, in a totally different context:

```java Nested logic lines theme={"system"}
while(theWorldTurns) {
  if(isMorning) {
    try {
      if (env.debugMode()) {
        System.out.println("Hello, world!");
      }
    } catch (BadDay e) {
      System.out.println("Yikes!");
    }
  }
}
```

In this example, the same conditional adds more complexity. Context matters.

The following count as nesting:

* 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:

```php Switch/case in PHP lines theme={"system"}
<?php
switch ($meal) {
    case "breakfast":
        echo "Most important meal of the day! Enjoy.";
        break;
    case "lunch":
        echo "A reasonably important meal of the day.";
        break;
    case "dinner":
        echo "Alright, rounding out your day, very nice.";
        break;
    default:
       echo "Snacking is important!";
}
```

This code is perfectly intuitive to understand, but if you wanted to test it exhaustively, you would need to write at least four test cases. This is what we mean when we say its Cyclomatic Complexity is higher than its (cognitive) Complexity.

## Further reading

Please see the *[Cognitive Complexity: A new way of measuring understandability][paper]* white paper by G. Ann Campbell of [SonarSource](https://www.sonarsource.com/) for further detail and many examples.

[qm-blog]: http://blog.codeclimate.com/blog/2017/09/21/a-new-clearer-way-to-understand-code-quality/

[paper]: https://www.sonarsource.com/docs/CognitiveComplexity.pdf

## See Also

* [Analysis Configuration](/analysis-configuration)
* [Code Smells](/code-smells)
* [Duplication](/duplication)
