posted on Sunday, January 09, 2005 8:15 PM by johnwood

Source Code Metrics Pt 2: Complexity

(Impatients: You can download an alpha release of a simple, command-line complexity analyzer here).
 
So the next area I'm tackling is complexity metrics. How do we measure how complex source code is?
 
Of course, to get a perfectly accurate measure is next to impossible. And even if you can measure the complexity of source code, maybe the complexity is justified because the requirements are complex - and quantifying the complexity of the requirements is a project unto itself.
 
But, however imperfect they may be, there are some useful metrics out there that we can deduce from analyzing source code. And again, I think it would be quite useful to have this somehow reported during our nightly build, so I wrote a command line tool that would provide me with this information.
 
The complexity metric that I'm going to use is called the Cyclomatic Complexity index, and it basically measures the complexity of a single method based on the number of independent code paths (decisions) that occur in that method. This includes 'if' statements (and each logical condition within the if statement), 'while' and 'for' loops, 'switch' statements, and basically any code form that results in a decision being made.
 
For example, the following method would have a CC of 2 (all methods start out with a CC of 1, there is 1 branch for the if true, and 1 branch for the else):
 
bool ValidateAge(int age)
{
    if (age<21)
        return false;
    else
        return true;
}
 
I've then combined this with the Weighted Methods Per Class index to come up with a complexity index that also takes into account the number of methods per class. This index sums the complexity index for each method in a class, and then averages this out across all classes. The resultant figure should be in the range of 1 - 200, anything above 200 is considered to be questionable and anything about 400 is considered to be in need of a serious refactoring.
 
As I said before I've put this into a command line tool which I'm currently testing. If anyone else wants to try it, they can find the binary here. The utility works by disassembling the code and counting any branch instruction as a decision point.
 
You would run the utility as:
 
    ccmetrics c:\mystuff\mybinary.exe
 
It takes any executable or DLL as an argument, and works with any .net language.
 
Let me know if you find any problems!
 

Comments