31

W.r.t to one of the java projects, we recently started using SonarLint. Output of the code analysis shows too many critical code smell alerts.

Critical code smell: Refactor this method to reduce its Cognitive Complexity.

I have heard about Cyclomatic Complexity but not about Cognitive Complexity. My questions to the group:

  • Is Cognitive Complexity an industry standard?
  • Impacts of Cognitive Complexity on code apart from readability and maintainability.
  • Does Cognitive Complexity apply only to methods or any other parts of code?
  • Any specific criteria on which Cognitive Complexity depends on?
  • Best practices to improve Cognitive Complexity of a code.

I have gone through this link but could not get answers to all my questions.

Thanks in advance.

vmorusu
  • 936
  • 1
  • 15
  • 32
  • 2
    That link also includes a link to a white paper on the subject with more details. Have you gone through that too? – janos Oct 10 '17 at 19:16
  • Thanks for pointing out that. I had missed. Info in that white paper looks to be sufficient for a developer to have a decent understanding of Cognitive Complexity and how to approach it. – vmorusu Oct 10 '17 at 20:36
  • You can also have a look at this answer for an explanation of how cognitive complexity is calculated and how it be reduced: https://stackoverflow.com/a/62867219/7730554 – Andreas Hütter Dec 18 '21 at 16:46

2 Answers2

37

Humans can easily keep in mind about 7 entities +/- 2(wikipedia). When somebody needs to read the code they may run into this limit. Sometimes there are too many local variables to keep track of, or too many if/for statements. In all cases it makes it harder to understand what the code is supposed to do because it's hard to keep a mental picture of the algorithm.

Industry standard: No.

Readability and maintainability: It's easier to debug/improve code that is simple and easy to read.

Applies on methods or other parts: Everything that some human might want to understand. If you try to explain your design and I need to keep track of 20+ classes, I'll be lost. If I need to work quickly with your interface but I need to remember 10 bits of state, I won't be able to.

Any specific criteria it depends on: The amount of things one needs to remember to understand the code.

Best practices: Make more and better defined functions. Extract related concepts into groups/packages. Reduce the number of nesting levels in the code (if you read a nested code you need to remember the condition that got you there). Reduce the number of in use variables at any one point (works great with extracting functions).

Sorin
  • 11,863
  • 22
  • 26
  • With your comments, it looks like we can apply Cognitive Complexity in any field, not only just coding. Let me explore its applicability in different aspects. Thanks. – vmorusu Oct 11 '17 at 15:10
0

Code complexity is a useful metric if you are writing 'old style' java, meaning lots of ifs and loops. When you are writing more 'new style' java, with stream, filter, map, reduce and other lambdas, the cognitive complexity is not very useful.

For example I have a class of about 350 effective lines with 35 methods that has a total cognitive complexity of 14. I assure you that code is harder to understand than a few loops and ifs. Actually 25 of those 35 methods have a cognitive complexity of 0...

Edit: Add example

For example this method has a cognitive complexity of 0:

public Mono<Void> handle(WebSocketSession session) {
    return session
        .send(events
            .filter(this::shouldBeIncluded)
            .map(this::toJsonText)
            .map(session::textMessage))
        .and(session
            .receive()
            .map(WebSocketMessage::getPayloadAsText)
            .map(this::handleMessage));
}

This is 'new style' java, using chained calls, streams, etc. For this cognitive complexity is less useful. While this code is much easier to read than its 'old' counterpart, which would use statements like if(shouldBeIncluded(event)) { ... }, the cognitive load for this method is still not zero.

Cyclomatic complexity is basically the path count divided by the method count where cognitive complexity tries to be smarter for example by adding more penalty for deeper nesting. It just doesn't work as well for 'new style' code.

Redshift
  • 11
  • 1
  • 2
  • i think you are wrong and mistake cognitive complexity and cyclomatic complexity – underwater ranged weapon Aug 30 '22 at 14:54
  • I have written scanners for these metrics (using the Sonar white paper for cognitive complexity and mcCabe’s wikipedia entry for cc) and scanned my code with it. So these are actual values from my code and not some made up stuff. Easy to just dismiss them and give a -1 without so much as an argument. – Redshift Aug 31 '22 at 15:41
  • I’ll add examples when I have time. One example here: function compute() { return (some + formula) / here; } has a cognitive complexity of 0. A class with 20 of these methods also has a total cognitive complexity of 0. – Redshift Aug 31 '22 at 15:58
  • you added example that is egainst you lol, yeah cognitive complexity of this piece of code is low because you somehow isolated what is going co its fairly easy to understand, even i not knowing what methods in stream are doing i can tell you its clear what this piece of code is doing. Read https://www.sonarsource.com/docs/CognitiveComplexity.pdf first. There nothing like old style and new style lol. you showed functional approach with method chaining its not new it's different – underwater ranged weapon Sep 01 '22 at 13:20