Channels ▼
RSS

.NET

Measuring Complexity Correctly


Code complexity is an important and valid metric. Its most common unit of measure is derived via cyclomatic complexity and is frequently referred to as the cyclomatic complexity number, or CCN. To be historically complete, the same measure was once known as "McCabe," because it was originally proposed by Tom McCabe in 1976. The CCN basically measures the number of possible execution paths through a piece of code, generally a function. So code with a single path (that is, no if statements or loops) has a CCN of 1, the minimum possible value. The CCN rises with if statements, looping constructs, and other code features that involve a test before deciding what code to execute.

Typically, it's desirable for routines to have a CCN below 10. Most tools that measure code quality get fairly noisy if they find CCNs above 20. The idea behind these guidelines is that the more complex code is, the harder it is to test and maintain. Code that is hard to test and maintain tends to be a honey pot for bugs.

Organizations that pay attention to quality metrics will often put in a place a system that refuses to allow check-ins of code in which the CCN surpasses a preset limit. This would work except for one imperfection in the CCN as it is measured today, namely that every case statement in a switch represents a different path and so raises the CCN. So, a routine with a case statement containing more than 30 cases will have a CCN greater than 30 and be blocked at check in. There are ways around this, of course, but the switch statement is designed precisely to reduce the complexity of large-scale multiway value-based decisions. There is no doubt that a 20-case switch is less complex than code whose logic is 20 levels deep. This is a small defect in CCN computation, which otherwise is a good measure: It is simple to calculate, easy to evaluate, and universally deployed in QA tools.

However, for CCN to be useful, it needs to be applied correctly. Many people apply the CCN measure to a whole program or to an entire source file. This approach generates a meaningless number. The resulting number is the sum of the CCNs of the individual routines. This means that the more routines in the file, the higher the CCN. It says nothing about whether the code is complex or not. This misunderstanding is rife in our industry, which is why the CCN is far too often ignored. A recent example of this very thing, to my surprise, appears in VS 2012, as I noted in our recent review of the product. The VS 2012 code review option generates the data in the following box (see column 3):


Cyclomatic Complexity in Column 3 is the sum of CCNs of constituent functions.

As can be seen, the CCN is meaningless when computed this way. If taken at face value, all those entries are off-the-charts complex. A CCN of 137 for example (the highlighted item) is unimaginably complex code. But, in fact, the CCN in this dialog is the sum of the CCNs of the various methods in the class, which has 222 lines of code. Had Microsoft at least shown the average CCN per method, developers would have some sense of where to look for problems. But the right path would be to omit CCNs entirely from code at the class level, and to present a separate dialog listing the methods and functions with the highest CCNs. Then, developers could go in and fix the code if necessary.

The typical fixes for high-complexity code include refactoring the code, frequently into smaller functions or classes that break up the complexity. Highly complex code is often indicative of violations of the single responsibility principle (SRP) — although not always. For example, parser code is frequently tagged with high CCNs and yet respects the SRP and is devilishly difficult to simplify. In such cases, adding comments is often a good path. This at least helps maintainers work their way through the code. Finally, occasional Dr. Dobb's author Andrew Glover points out that if you're committed to thorough testing, a good rule of thumb is that you should have, at minimum, one unit test for every increment in CCN. So a function with a CCN of 17 should have at least 17 unit tests — one for each possible execution path.

Either way, if you rely on CCN as a useful code metric, and I believe you should, apply it correctly so that it delivers true value.

— Andrew Binstock
Editor in Chief
alb@drdobbs.com
Twitter: platypusguy


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video