Do you find cyclomatic complexity a useful measure?

I've been playing around with measuring the cyclomatic complexity of a big code base.

Cyclomatic complexity is the number of linearly independent paths through a program's source code and there are lots of free tools for your language of choice.

The results are interesting but not surprising. That is, the parts I know to be the hairiest were in fact the most complex (with a rating of > 50). But what I am finding useful is that a concrete "badness" number is assigned to each method as something I can point to when deciding where to start refactoring.

Do you use cyclomatic complexity? What's the most complex bit of code you found?


Solution 1:

We refactor mercilessly, and use Cyclomatic complexity as one of the metrics that gets code on our 'hit list'. 1-6 we don't flag for complexity (although it could get questioned for other reasons), 7-9 is questionable, and any method over 10 is assumed to be bad unless proven otherwise.

The worst we've seen was 87 from a monstrous if-else-if chain in some legacy code we had to take over.

Solution 2:

Actually, cyclomatic complexity can be put to use beyond just method level thresholds. For starters, one big method with high complexity may be broken into several small methods with lower complexity. But has it really improved the codebase? Granted, you may get somewhat better readability by all those method names. But the total conditional logic hasn't changed. And the total conditional logic can often be reduced by replacing conditionals with polymorphism.

We need a metric that doesn't turn green by mere method decomposition. I call this CC100.

CC100 = 100 * (Total cyclomatic complexity of codebase) / (Total lines of code)

Solution 3:

It's useful to me in the same way that big-O is useful: I know what it is, and can use it to get a gut feeling for whether a method is good or bad, but I don't need to compute it for every function I've written.

I think simpler metrics, like LOC, are at least as good in most cases. If a function doesn't fit on one screen, it almost doesn't matter how simple it is. If a function takes 20 parameters and makes 40 local variables, it doesn't matter if its cyclomatic complexity is 1.

Solution 4:

Until there is a tool that can work well with C++ templates, and meta-programming techniques, it's not much help in my situation. Anyways just remember that

"not all things that count can be measured, and not all things that can be measured count" Einstein

So remember to pass any information of this type through human filtering too.