Saturday, April 16, 2011

Code Metrics

Well, back again. Microsoft has been using FxCop for its own code analysis purposes for long. With Visual Studio 2008, the code analysis rules were integrated into the IDE itself under the new "Analyze" menu. I will leave static code analysis for some other day. Right now, I am interested in the "Code Metrics" option under Analyze.

Code metrics is a set of measures that helps you to analyze your code and indicates the complexity or maintainability of the code. There are a number of measures out there that you can use to analyze our code. Microsoft uses the best few and provides statistics about your code. Visual Studio provides you statistics on the lines of code, class coupling, depth of inheritance and most importantly, the cyclomatic complexity. Open a project in Visual Studio, go to "Analyze" and select "Calculate Code Metrics..." option.

When the code metrics is calculated for the project, the results are displayed in a window. The result window contains the metrics for each and each of their methods (functions).

Against each class/method, what we can see is a numeric value as Maintainability Index, Cyclomatic Complexity, Depth of Inheritance, Class Coupling and Lines of Code. So what these terms really mean?

  • Cyclomatic Complexity
                  Cyclomatic complexity is defined at the method level. It indicates the structural complexity of the method. The cyclomatic complexity of a method is the count of the total number of independent paths in the method. So, each branch (if, else, select etc.) and each loop (for, while etc.) counts towards the cyclomatic complexity of the method. The more number of branches and loops within a method, the higher the complexity. The cyclomatic complexity of a method has a direct impact on the maintainability and testability of the code, and it has been one of the successful and useful measures of code complexity.

                 The following table explains the range of values and the associated risk.

Cyclomatic Complexity Risk Evaluation
1-10 simple module, not risky
11-20 moderately complex, moderate risk
21-50 complex method, high risk
>50 a very complex and unstable method, very high risk

Further details on how to calculate cyclomatic complexity can be found here.

  • Depth of Inheritance
                 The depth of inheritance is defined at the class level. It is the number of classes that the current class extends till the root of the class hierarchy. The deeper the hierarchy, he higher is the complexity of code.

                 A class hierarchy up to depth 6 is acceptable. Anything higher should be subjected to a revision of the class hierarchy.

  • Class Coupling
                 Class Coupling is defined at the class level. It is the number of classes the current class is coupled with (interacts with). The interaction can be in any form e.g. function calls, returning parameters etc. A class is considered more stable if it is less coupled (i.e. it is more cohesive in nature). Less coupling means there are lesser chances of the class breaking other classes or getting broken by a change in other classes.

                 Although it highly depends on the design and architecture followed, a coupling indicator above 30-40 should be subjected to revision.

  • Lines of Code
                 Lines of code indicate the number of lines of code in a method or a class. Visual Studio counts the number of lines in the IL code and can differ from the lines of code in the source file. This is an old measure of code complexity and can be highly misleading. However, it must be accepted that a method or a class of a huge size is not easily maintainable.

                 While there is no hard and fast rule on the range of lines of code a method or a class should have, it is advised to limit a method below 60 lines of code and a class below 1500 lines of code.

  • Maintainability Index
                 Maintainability Index is a calculated measure based on the above measures that Visual Studio uses to indicate whether method or a class is maintainable. Maintainability Index per module is calculated using the following formula:

Maintainbility Index = 171 - 5.2 * avg (Halstead Volume) - 0.23 * (Cyclomatic Complexity) - 16.2 * avg(Lines of Code)

, where Halstead volume is a measure calculated from the number of operators and operands in the module.

                 A module is considered maintainable if its maintainability index is in a higher range. The index is calculated in a range of 0-100, where 0 being the least maintainable and 100 being the most maintainable. The following table explains the range of values and their meaning.

Maintainability Index Maintainability of Code
20-100 Code is very maintainable (indicated as green)
10-19 Code is moderately maintainable (indicated as yellow)
0-9 Code has poor maintainability (indicated as red)

Although an index above 20 is considered maintainable, it is advised to keep the maintainability index higher than 50 for well maintainable code.

Code metrics is is available only in Visual Studio Team System editions, not in Professional or Standard Editions. However, there are other utilities available including the command line based Code Metrics PowerTool from Microsoft itself that can serve the purpose if you do not have the Team System editions. I will write another post on how to use the PowerTool, but hope this post helps you to understand and get familiar with code metrics in Visual Studio.