Insights in Cyclomatic and Cognitive Complexity in Your Application
Everybody who’s ever been exposed to a legacy codebase knows the feeling of not having any idea where to get started. You start opening some random files, looking through the code, hoping to get a grasp on how this project works. You size up the project and try to pinpoint problem areas that are suitable for the first refactoring attempts.
I wished that developers included more documentation and diagrams so others can more easily get an oversight of how things work. This would help in preparing roadmaps and communicating the effort to clean up technical debt to product departments and management. Luckily enough I came across a toolset that helped me size up the cyclomatic and cognitive complexity in the codebase and coordinate the refactoring efforts.
What is cyclomatic complexity?
Cyclomatic complexity is a quantitative indication of how difficult the code is to comprehend. If a program is drawn out as a graph with vertices (nodes) and edges then the following calculation results in the cyclomatic complexity:
M = E - N + 2P
Where M is the resulting complexity, E is the number of edges, N is the number of vertices and P is the number of possible exit points.
Let’s take the following PHP code and calculate the cyclomatic complexity:
The above code can be translated in the following graph:
In the graph, there are 5 vertices, 7 edges. In simple cases likes these we consider the return points as a single string return. Throwing an exception would be an example where we can consider two exit points. This leads to the following cyclomatic complexity calculation:
M = E — N + 2P
E = 7
N = 5
p = 1
M = 7- 5+ 2 * 1= 4
To give you a general idea of how this quantitive data transfers into a feeling of complexity, here’s how the Software Engineering Institute classed different levels of cyclomatic complexity:
1–10 a simple program, without much risk
11–20 more complex, moderate risk
21–50 complex, high risk
>50 an untestable program, very high risk
Where does cognitive complexity come in?
Now lay the code we’ve just seen beside the following code:
Both of these code snippets have a cyclomatic complexity of 4 whilst this code is clearly much harder to understand. Cyclomatic complexity is simply bound to the number of lines of code and the number of control structures (if, while, switch) used. We miss a form of context to judge the complexity of the code.
SonarQube came up with the concept of cognitive complexity in order to introduce a more contextualized form of quantitive data on code complexity. The complexity is assessed based on these three basic rules:
- Ignore structures that allow multiple statements to be readably shorthanded into one.
- Increment (add one) for each break in the linear flow of the code.
- Increment when flow-breaking structures are nested.
If you would like to further understand the context of cognitive complexity, check out the whitepaper SonarQube published on the matter.
But how does this help us? Well following the rules of cognitive complexity the first code example boils down to a cognitive complexity of 1 whilst the second example is a complexity of 7. This shows the contrast between the Cognitive and Cyclomatic Complexities and how cognitive Complexity judges more based on the code’s context.
Great, but how does this help me in large codebases?
So obviously we’re not going to calculate the cognitive complexity of every method within our codebase. How does this concept help us determine the paths to take inside our project?
This is where the combination of SonarQube and the plugin SoftVis3d come into play. Using this plugin you can visualize your codebase based on the lines of code, issues, expected bugs, security vulnerabilities, cyclomatic complexity, cognitive complexity, etc. The code is sorted by directory and each file is represented as a bar chart. You could also consider this a house or flat in a neighborhood if you will.
If we pick the building height as the number of lines of codes and the floor space as cognitive complexity the most ideal situation would be a nice suburb with small houses and nice gardens. However, in some cases, you might end up with the New York City skyline.
Eventually, this helps you tear down the flats and replace them with small buildings where you have your concerns separated and your coupling kept to a minimum. If you’re looking for a nice example to see the idea in action check out Jenkins’ public SonarQube.
Conclusion
We’ve looked at the concept of cognitive complexity which gives us some insights into the structural complexity of our codebase. In order to fill the gap of not having contextualized quantitative data SonarQube has invented cognitive complexity which is a more in-depth analysis of the complexity. In the end, we plotted this data into SoftVis3D which gave us a visualized idea of the structure of our codebase.
At Takeaway we’re always looking to improve the quality of our work. We manage our complexity and quality using SonarQube and the SoftVis3D plugin amongst other cool tools. Make sure to check out our careers page to discover Tech jobs at Takeaway.com!
If you’ve got any thoughts, questions or concerns reach out in the comment or get in touch on twitter.
Update:
The softvis3d view for Elasticsearch is no longer available. An alternate example of Jenkins is available here:
https://softvis3d.com/sonar/project/extension/softvis3d/overview_page?id=org.jenkins-ci.main%3Ajenkins-parent&qualifier=TRK
Sources:
https://www.sonarsource.com/resources/white-papers/cognitive-complexity
https://resources.sei.cmu.edu/asset_files/Handbook/1997_002_001_16523.pdf
https://softvis3d.com/sonar/project/extension/softvis3d/overview_page?id=org.elasticsearch:elasticsearch (no longer available)
https://softvis3d.com/sonar/project/extension/softvis3d/overview_page?id=org.jenkins-ci.main%3Ajenkins-parent&qualifier=TRK