Interested in our Static Analysis?

← All posts
Julien Delange Friday, July 15, 2022

# A guide to software complexity that anyone can understand

Share

AUTHOR

#### Julien Delange, Founder and CEO

Julien is the CEO of Codiga. Before starting Codiga, Julien was a software engineer at Twitter and Amazon Web Services.

Julien has a PhD in computer science from Universite Pierre et Marie Curie in Paris, France.

See all articles

"Programs must be written for people to read, and only incidentally for machines to execute."

Abelson and Sussman (1985)

In this blog, we delve into software complexity. We first explain what software complexity is, show how you can find complex code in your Git repository, and then present some techniques to reduce software complexity.

## What is software complexity?

The most accepted method to quantify software complexity is the Cyclomatic Complexity. The cyclomatic complexity is a measure the number of independent paths in a program. The number of paths in a program is calculated based on a control flow graph.

Let's take the following Python code:

```.css-1buza8y{display:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:absolute;white-space:nowrap;vertical-align:middle;outline:2px solid transparent;outline-offset:2px;width:auto;line-height:1.2;border-radius:var(--chakra-radii-base);font-weight:var(--chakra-fontWeights-semibold);transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-normal);height:auto;min-width:var(--chakra-sizes-8);font-size:var(--chakra-fontSizes-xs);-webkit-padding-start:var(--chakra-space-3);padding-inline-start:var(--chakra-space-3);-webkit-padding-end:var(--chakra-space-3);padding-inline-end:var(--chakra-space-3);box-sizing:border-box;background:var(--chakra-colors-white);-webkit-background-clip:padding-box;background-clip:padding-box;color:var(--chakra-colors-brand-red);padding-top:var(--chakra-space-1);padding-bottom:var(--chakra-space-1);right:var(--chakra-space-2);top:var(--chakra-space-2);font-family:var(--chakra-fonts-heading);}.css-1buza8y:focus,.css-1buza8y[data-focus]{box-shadow:var(--chakra-shadows-outline);}.css-1buza8y[disabled],.css-1buza8y[aria-disabled=true],.css-1buza8y[data-disabled]{opacity:0.4;cursor:not-allowed;box-shadow:var(--chakra-shadows-none);}.css-1buza8y:hover,.css-1buza8y[data-hover]{color:var(--chakra-colors-brand-red);-webkit-text-decoration:none;text-decoration:none;}.css-1buza8y:hover[disabled],.css-1buza8y[data-hover][disabled],.css-1buza8y:hover[aria-disabled=true],.css-1buza8y[data-hover][aria-disabled=true],.css-1buza8y:hover[data-disabled],.css-1buza8y[data-hover][data-disabled]{background:initial;}.css-1buza8y:hover::before,.css-1buza8y[data-hover]::before{background-image:linear-gradient(to right, var(--chakra-colors-brand-orange), var(--chakra-colors-brand-orange));}.css-1buza8y::before{content:'';position:absolute;top:0px;right:0px;bottom:0px;left:0px;z-index:-1;margin:-1px;border-radius:inherit;background-image:linear-gradient(to right, var(--chakra-colors-brand-pink), var(--chakra-colors-brand-orange));}.chakra-ui-dark .css-1buza8y:not([data-theme]),[data-theme=dark] .css-1buza8y:not([data-theme]),.css-1buza8y[data-theme=dark]{background:var(--chakra-colors-white);color:var(--chakra-colors-brand-red);}```def myfunc(a: int, b: int) -> int:
c = 10
if a > 100:
if b < 50:
c = 5
else:
c = 20
else:
c = 3
return a + b * c
``````

There is the corresponding control flow graph of the program. We annotated each node with its corresponding code. Each node in the graph is a circle, and an edge is an arrow going from one node to another.

The complexity is defined as

``````Complexity = (Number of Edges)
- (Number of Nodes)
+ 2 * (Number of Connected Components)
``````

## Other types of complexity

There are other contributors to software complexity, one being the size of your code and, more particularly, the length of a function.

One rule is that your code should always fit on your screen so you can read it and understand its control flow without scrolling.

## How to find complex code

Text editors and IDE often have tools or plugins to evaluate the complexity of your code (example for Visual Studio or JetBrains). Such tools often depend on the language because they must parse the program and build its control flow.

Additionally, some tools highlight long functions and warn the developer when a function is becoming unreadable. Codiga finds complex and long functions in code and flags complex and long functions either on push or pull requests. Codiga annotates code in its interface and highlights complex (e.g. function having high cyclomatic complexity) and long functions, as shown below.

Codiga also lets you change complexity thresholds. By default, the Codiga code analysis engine flags any function with a cyclomatic complexity higher than 25 and any function longer than 40 lines. These thresholds can be changed in the project configuration.

Find Complex Code with Codiga

Once you find complex code, it's now time to reduce it!

## How to reduce software complexity

Let's remember the cyclomatic complexity formula. Based on a control graph, the cyclomatic complexity is defined as:

``````Complexity = (Number of Edges)
- (Number of Nodes)
+ 2 * (Number of Connected Components)
``````

What increases complexity is not the number of nodes. It's the number of connected nodes in the control flow graph. The more you add nodes and connect them, the higher the complexity.

Looking at programming languages, there are the programming constructs that incur complexity:

• Nested branches: nested branches add new nodes in your control graph but also at least two connections for each new node
• `goto`, `continue` and `break` statement: `goto` statements add more connections between nodes in the control graph

Therefore, to reduce software complexity, you should:

• Write small functions: it reduces the number of nodes in your control graph. It reduces the size of the control graph and therefore, the number of edges. It also makes the code easier to understand.
• Avoid `goto`, `continue` and `break` statements: removing unnecessary connections between nodes of the control graph.

## Wrapping Up

The state-of-the-art metric to evaluate software complexity is the Cyclomatic Complexity. This metric defines software complexity as the number of connections in your control graph.

There are multiple tools available to calculate software complexity. A simple tool is Codiga which flags functions with high cyclomatic complexity. Codiga also flags long functions. Codiga requires no setup and provides complexity metrics for more than 15 languages.

To reduce software complexity, developers must write small units of code (function, procedure, methods) but also avoid statements (goto, break, continue) that make the code harder to understand and increase its complexity.

Are you interested in Datadog Static Analysis?