Programming Tools: Code Complexity Metrics
Recently, I was asked to maintain some old code and test some new code. Both tasks required that I understand the code with which I was working. Most of the time, these jobs are non-trivial due to the complexity of most code. At least four items can make things complex:
the obvious problem of understanding what is written
what the code is supposed to do, both at the macro and micro level
the environment in which the code is to run
the assumptions made about each of these things
A lot of tools are available to help sort out each of these issues. Few programs out there, however, try to measure the complexity of the code. I define complexity of code as the amount of effort needed to understand and modify the code correctly. As I explain in this article, computing complexity metrics often is a highly personal task. Also, few metrics have been shown to be of real value in determining the amount of effort needed to maintain or test code.
Performance metrics measure how well a valid program executes. Profiling tools fall into this category, and many tools are available. But for maintenance metrics, there are surprising few tools. Therefore, this column concerns creating a maintenance metric tool that measures complexity. It can be used as a prototype for general tools in other languages.
Maintenance metrics also are called static metrics because they are based on the source code. I subdivide maintenance metrics into formatting metrics and logical metrics. Formatting metrics deals with such things as indentation conventions, comment forms, whitespace usage, naming conventions and so on. Logical metrics deals with such things as the number of paths through a program, the depth of conditional statements and blocks, the level of parenthesization in expressions, the number of terms and factors in expressions, the number of parameters and arguments used and the like.
Complexity metrics depend on both of these types of maintenance metrics. For example, poor naming conventions can make any program hard to understand, and poor logical constructs can add to the difficulty of dealing with the code.
Another thing to notice is the number of factors that can be defined when measuring complexity. For example, you may find something easy to understand, while I may find it difficult. Given this, it would be presumptive of me to tell you how complex your code is. To solve this problem, I remembered how relational databases handle reporting.
If there is some way of finding elements of a program, putting them into a explicit context and then writing them to a row in a table, we then could use SQL-like facilities to analyze the data in any desired way. That said, we can cheat a little. While writing the records, standard metrics can be computed that may handle most needs.
The McCabe Cyclomatic Metric was introduced by Thomas McCabe in 1976. It probably is the most useful logical metric. It measures the number of linearly independent paths through a program. For example, for a simple function that has no conditionals, only one path exists. This straight-line code usually is easy to follow. Programs that have many conditionals, in turn, are harder to follow. The difficulty also increases if multiple ways of exiting the program exist. That is why it often is a headache to debug a program with many exits.
The McCabe metric is:
M = E - N + X
where M is the McCabe Cyclomatic Complexity (MCC) metric, E is the number of edges in the graph of the program, N is the number of nodes or decision points in the graph of the program and X is the number of exits from the program.
In programming terms, edges are the code executed as a result of a decision--they are the decision points. Exits are the explicit return statements in a program. Normally, there is one explicit return for functions and no explicit return for subroutines.
A simpler method of computing the MCC is demonstrated in the equation below. If D is the number of decision points in the program, then
M = D + 1
Here, decision points can be conditional statements. Each decision point normally has two possible paths.
MCC also is useful in determining the testability of a program. Often, the higher the value, the more difficult and risky the program is to test and maintain.
Some standard values of Cyclomatic Complexity are shown in Table 1:
Table 1. Standard Values of Cyclomatic Complexity
| Cyclomatic Complexity | Risk Complexity |
|---|---|
| 1-10 | a simple program, without much risk |
| 11-20 | more complex, moderate risk |
| 21-50 | complex, high risk |
| 51+ | untestable, very high risk |
One final word on MCC that also applies to most of the other metrics: each element in the formulae is assumed to have the same weight. In MCC's case, both branches are assumed to be equally complex. However, in most cases this is not the case. Think of the if statement with code for only one branch--yet each branch is treated as having the same weight. Also, measures of expressions are all the same, even for those that contain many factors and terms. Be aware of this and be prepared, if your tool gives you the ability, to add weight to different branches. This metric is called an Extended McCabe Complexity Metric.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- Designing Electronics with Linux
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- Validate an E-Mail Address with PHP, the Right Way
- Build a Skype Server for Your Home Phone System
- Why Python?
- A Topic for Discussion - Open Source Feature-Richness?
- Tech Tip: Really Simple HTTP Server with Python
- Great
3 hours 31 min ago - Reply to comment | Linux Journal
3 hours 39 min ago - Understanding the Linux Kernel
5 hours 54 min ago - General
8 hours 24 min ago - Kernel Problem
18 hours 27 min ago - BASH script to log IPs on public web server
22 hours 54 min ago - DynDNS
1 day 2 hours ago - Reply to comment | Linux Journal
1 day 3 hours ago - All the articles you talked
1 day 5 hours ago - All the articles you talked
1 day 5 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



Comments
There is a more standard metric
Function points are a more established metric than cyclomatic complexity.
Wrong
You're wrong in at least two aspects:
(1) function points are a measure of *volume*, not *complexity*. Two programs can have wildly different cyclomatic complexities, but the same function point score.
(2) McCabe's complexity is at least as well established as function points, at least among those who know enough of the literature to understand the difference between a volume and a complexity measure.
Function points
I have tried working with function points. The effort has not been successful for two main reasons. One, the definition of what consistutes a function point always seems to be in flux - making it almost a "black art". Second, most tools using function points seem to be proprietary and how they compute their function point metrics are secret. That said, there seems to be a strong community who support function points. A simple introduction for functions points can be found at http://www.ifpug.com/fpafund.htm