Comment by Waterluvian
5 years ago
Some take "line of code" literally. Others see it as a stand-in for complexity. Because one can certainly make a short program that's far more of a liability than a long one.
I'm wondering if there's a quality term for a "unit of complexity" in code? Like when a single line has 4 or 5 "ideas" in it.
There are many metrics for measuring the logic complexity of code. An early and best-known one is Cyclomatic Complexity [0] - The more possible execution paths, the higher the score. You can find more at Software Metric [1].
[0] https://en.wikipedia.org/wiki/Cyclomatic_complexity
[1] https://en.wikipedia.org/wiki/Software_metric
For VS Code have used this on the past: https://marketplace.visualstudio.com/items?itemName=kisstkon...
and this one https://marketplace.visualstudio.com/items?itemName=Stepsize...
These two haven't tried before but doing it now:
https://marketplace.visualstudio.com/items?itemName=selcuk-u...
https://marketplace.visualstudio.com/items?itemName=TomiTurt...
If there is a useful metric, then I haven't found it yet. The data on cyclomatic complexity[1] does not convince me, and in practice, the linters I've seen have complained about boring code like this:
There are 16 paths and yet this code is easy to follow. There is no substitute for human judgement (code reviews).
[1] https://en.wikipedia.org/wiki/Cyclomatic_complexity#Correlat...
> case KIND_15: return parseObjectOfKind5();
I don't like this type of code for exactly this reason.
15 replies →
It kind of encourages you to use a lookup table or polymorphism, which isn't far off from what the compiler is likely to do with that switch statement.
As for correlation to number of defects, another important factor is maintainability (velocity of new features in growing programs, keeping up with infrastructure churn in mature programs). If reducing perceived complexity improves maintainability, and if measuring cyclomatic complexity despite its flaws helps reduce perceived complexity, then it's still a useful metric.
4 replies →
That's what I was thinking about when I used "ideas". To me there's one main idea in all that code: "we are returning a parsed object of a kind"
Not that I'm trying to sell "ideas". I don't even know. But it's this very loose concept that floats around my mind when writing code. How many ideas are there in a stanza? Ahh too many. I should break out one of the larger ideas to happen before.
1 reply →
This is one of the benefits of Cognitive Complexity:
https://www.sonarsource.com/docs/CognitiveComplexity.pdf
>Switches
>A `switch` and all its cases combined incurs a single structural increment.
>Under Cyclomatic Complexity, a switch is treated as an analog to an `if-else if` chain. That is, each `case` in the `switch` causes an increment because it causes a branch in the mathematical model of the control flow.
>But from a maintainer’s point of view, a switch - which compares a single variable to an explicitly named set of literal values - is much easier to understand than an `if-else if` chain because the latter may make any number of comparisons, using any number of variables and values.
>In short, an `if-else if` chain must be read carefully, while a `switch` can often be taken in at a glance.
1 reply →
Except it's not easy to follow. Why does kind 15 return a parsed object of kind 5? That's not counting the complexity of each function called, either.
2 replies →
> The more possible execution paths, the higher the score.
Great! Now we can all begin to write branchless code. Make branch prediction miss a thing of the past!
You jest, but I had a manager who loved Cyclomatic complexity as a measure of programmer ability. I tried in vain to convince him that CC was measuring the complexity of the underlying business logic, not my programming ability.
I wasted a lot of brainpower cutting down CC in my code doing terrible things like storing function names as strings in hashmaps, i.e.,
Because that could replace several 'if' checks, since function calls weren't branches. Of course, no exception handling, because you could save branches by using throws Exception.
To this day, I wonder if Cyclomatic complexity obsession helped make "enterprise Java" what it is today.
1 reply →
Perfect. This is what I was curious about. Haven't heard of either. Thank you.
The real measure you want is the cyclomatic complexity divided by the complexity required by the problem. The problem with line counting (or cyclo counting) is that it assumes a constant ratio.
It is not trivial to understand the necessary complexity of a problem. In SICP, there's an early practice problem that asks you to turn a recursive number pattern generator into an iterative generator. What the problem doesn't tell you is that the generator obscured by complex recursion is actually creating a tribbonaci number sequence. This hidden insight turns a difficult problem into a trivial problem.
1 reply →
Developers have tried to build metrics for "complexity" over the years. Cyclomatic Complexity is often pointed to as one of the more successfully deployed: https://en.wikipedia.org/wiki/Cyclomatic_complexity
As with any metric, it's something to take as useful "advice" and becomes a terrible burden if you are optimizing for/against it directly. (Such as if you are incentivized by a manager to play a game of hitting certain metric targets.)
It's also interesting to note that a complete and accurate complexity metric for software is likely impossible due to it being an extension/corollary of the Halting Problem.
I'm definitely not encouraging writing "clever" short code. Always strive to write clear code. You write it once, but it will be read (and potentially changed) many, many times.
As for complexity metrics, this is a contentious topic. It's hard to quantify "ideas" or "concepts". I think this is the part where technical design reviews and good code reviews help keep in check.
My IDE spits out a warning when I reach a certain level of complexity in a method, using Mccabe's Cyclomatic Complexity as a measure. It roughly maps with "too many if statements" in my case.