I am new to static analysis of code. My application has a Cyclomatic complexity of 17,754. The application itself is only 37,672 lines of code. Is it valid to say that the complexity is high based on the lines of code? What exactly is the Cyclomatic complexity saying to me?
What exactly is the Cyclomatic complexity saying to me?
Cyclomatic complexity is not a measure of lines of code, but the number of independent paths through a module. Your cyclomatic complexity of 17,754 means that your application has 17,754 unique paths through it. This has a few implications, typically in terms of how difficult it is to understand and test your application. For example, the cyclomatic complexity is the number of test cases needed to achieve 100% branch coverage, assuming well-written tests.
A good starting point might be the Wikipedia article on cyclomatic complexity. It has a couple of snippits of pseudocode and some graphs that show what cyclomatic complexity is all about. If you want to know more, you could also read McCabe's paper where he defined cyclomatic complexity.
My application has a Cyclomatic complexity of 17,754 lines of code. The application itself is only 37,672 lines of code. Is it valid to say that the complexity is high based of the lines of code?
Not at all. An application with few lines of code and a high number of conditionals nested within loops could have an extremely high cyclomatic complexity. On the other hand, an application with few conditions might have a low cyclomatic complexity. That's oversimplifying it a big, but I think it gets the idea across.
Without knowing more about what your application does, it might be normal to have a higher cyclomatic complexity. I would suggest measuring cyclomatic complexity on a class or method level, however, instead of just an application level. This is a little more managable, conceptually, I think - it's easier to visualize or conceptualize the paths through a method than paths through a large application.
Cyclomatic complexity is a way to determine if your code needs to be refactored. The code is analyzed and a complexity number is determined. Complexity is determine by branching (if statements, etc.) Complexity also might take in to account nesting of loops, etc. and other factors depending on the algorithum used.
The number is useful at the method level. At higher levels it is just a number.
A number of 17,754 indicates project level complexity (total code), which doesn't have that much meaning.
Drilling down into class and method level complexity will determine areas of the code that need to be refactored into smaller methods or redesigned to elminate the complexity.
CASE statement with 50 cases in one method. Maybe each state has different business logic. That will generate a cyclomatic complexity of 50. There are 50 decision points. The CASE statement may have to be redesigned using a factory pattern to get rid of the branching logic. Sometimes you can refactor (break up the method into smaller parts) and in some cases only a redesign will reduce the complexity.
In general, for method level complexity:
- < 10 Easy to maintain
- 11-20 Harder to maintain
- 21+ Candidates for refactoring/redesign
Also consider that higher complexities make the code harder to unit test.
The highest complexity I have seen on a single method was 560. It was about 2000 lines of if statements in one method. Basically unmaintainable, untestable, full of potential bugs. Imagine all the unit test cases needed for that branching logic! Not good.
Try and keep all methods under 20 and realise there is a cost to refactoring any method to make it less complex.
It's the number of distinct paths in your application. Check out this IBM article on CC.
It seems high but in your case it is the addition of the CC of all your methods of all your classes and methods. My examples are far stretched since I don't know how your code is structured but you may as well have one monster method with 37672 lines of code or 3767 methods with about 10 lines of code. What I mean is that at the application-level, this indicator does not mean much, but at the method-level it may help you optimize/rewrite your code into smaller methods so that they are less prone to errors.
What I have personally read a lot of times is that methods with a CC higher than 10 have higher risks of defects.
I use Sonar to test code quality of my applications and by default I think it raises a warning if you have methods with +10 CC. Still that may mean nothing. One concrete example: if you use Eclipse to generate a
equals method based on the properties of your bean, the CC will very quickly go above the roof...
It de pends on which tool did you use. Some of the open source tool out there take class as an module or other level of structure as a module. Therefore, the bigger a project gets, the higher Cyclomatic Complexity it tends to get. However, for my personal understanding, it should be on a function base. Since the bigger a project gets, the functions it attends to have.
I recommend you to use the tool called Lizard and you can find the resource code and download the zip file at github. It also has a online version if there is not much confidential information in your code.
The meaningful CCN you should care about is on a function base other than any other. Plus, keep each function's CCN unber 15 would be the ideal range.