什么是循环复杂度?

我经常看到一个术语叫做“循环复杂度”。在这里,我看到了一些关于“如何计算语言 X 的 CC”或“如何用最小的 CC 做 Y”的问题,但我不确定我是否真正理解它是什么。

NDepend 网站中,我看到一个解释,基本上是说“方法中的决策数量。每个 if、 for、 & 等加上 CC“得分”+ 1)。真是这样吗?如果是的话,为什么不好呢?我可以看到,人们可能希望将 if 语句的数量保持在相当低的水平,以使代码容易理解,但这真的是它的全部吗?

还是有更深层次的概念?

19419 次浏览

I'm not aware of a deeper concept. I believe it's generally considered in the context of a maintainability index. The more branches there are within a particular method, the more difficult it is to maintain a mental model of that method's operation (generally).

Methods with higher cyclomatic complexity are also more difficult to obtain full code coverage on in unit tests. (Thanks Mark W!)

That brings all the other aspects of maintainability in, of course. Likelihood of errors/regressions/so forth. The core concept is pretty straight-forward, though.

Yep, that's really it. The more execution paths your code can take, the more things that must be tested, and the higher probability of error.

That's it, the idea is that a method which has a low CC has less forks, looping etc which all make a method more complex. Imagine reviewing 500,000 lines of code, with an analyzer and seeing a couple methods which have oder of magnitude higher CC. This lets you then focus on refactoring those methods for better understanding (It's also common that a high CC has a high bug rate)

Cyclomatic complexity measures the number of times you must execute a block of code with varying parameters in order to execute every path through that block. A higher count is bad because it increases the chances for logical errors escaping your testing strategy.

Each decision point in a routine (loop, switch, if, etc...) essentially boils down to an if statement equivalent. For each if you have 2 codepaths that can be taken. So with the 1st branch there's 2 code paths, with the second there are 4 possible paths, with the 3rd there are 8 and so on. There are at least 2**N code paths where N is the number of branches.

This makes it difficult to understand the behavior of code and to test it when N grows beyond some small number.

Consider the control flow graph of your function, with an additional edge running from the exit to the entrance. The cyclomatic complexity is the maximum number of cuts we can make without separating the graph into two pieces.

For example:

function F:
if condition1:
...
else:
...
if condition2:
...
else:
...

Control Flow Graph

Control Flow Graph

You can probably intuitively see why the linked graph has a cyclomatic complexity of 3.

Cyclomatric complexity is basically a metric to figure out areas of code that needs more attension for the maintainability. It would be basically an input to the refactoring. It definitely gives an indication of code improvement area in terms of avoiding deep nested loop, conditions etc.

Wikipedia may be your friend on this one: Definition of cyclomatic complexity

Basically, you have to imagine your program as a control flow graph and then

The complexity is (...) defined as:

M = E − N + 2P

where

  • M = cyclomatic complexity,
  • E = the number of edges of the graph
  • N = the number of nodes of the graph
  • P = the number of connected components

CC is a concept that attempts to capture how complex your program is and how hard it is to test it in a single integer number.

Cyclomatic Complexity really is just a scary buzzword. In fact it's a measure of code complexity used in software development to point out more complex parts of code (more likely to be buggy, and therefore has to be very carefully and thoroughly tested). You can calculate it using the E-N+2P formula, but I would suggest you have this calculated automatically by a plugin. I have heard of a rule of thumb that you should strive to keep the CC below 5 to maintain good readability and maintainability of your code.

I have just recently experimented with the Eclipse Metrics Plugin on my Java projects, and it has a really nice and concise Help file which will of course integrate with your regular Eclipse help and you can read some more definitions of various complexity measures and tips and tricks on improving your code.

Another interesting point I've heard:

The places in your code with the biggest indents should have the highest CC. These are generally the most important areas to ensure testing coverage because it's expected that they'll be harder to read/maintain. As other answers note, these are also the more difficult regions of code to ensure coverage.

That's sort of it. However, each branch of a "case" or "switch" statement tends to count as 1. In effect, this means CC hates case statements, and any code that requires them (command processors, state machines, etc).

The answers provided so far do not mention the correlation of software quality to cyclomatic complexity. Research has shown that having a lower cyclomatic complexity metric should help develop software that is of higher quality. It can help with software quality attributes of readability, maintainability, and portability. In general one should attempt to obtain a cyclomatic complexity metric of between 5-10.

One of the reasons for using metrics like cyclomatic complexity is that in general a human being can only keep track of about 7 (plus or minus 2) pieces of information simultaneously in your brain. Therefore, if your software is overly complex with multiple decision paths, it is unlikely that you will be able to visualize how your software will behave (i.e. it will have a high cyclomatic complexity metric). This would most likely lead to developing erroneous or bug ridden software. More information about this can be found here and also on Wikipedia.

Cyclocmatic complexity = Number of decision points + 1

The decision points may be your conditional statements like if, if … else, switch , for loop, while loop etc.

The following chart describes the type of the application.

  • Cyclomatic Complexity lies 1 – 10  To be considered Normal applicatinon

  • Cyclomatic Complexity lies 11 – 20  Moderate application

  • Cyclomatic Complexity lies 21 – 50  Risky application

  • Cyclomatic Complexity lies more than 50  Unstable application

Cyclomatic complexity is computed using the control flow graph. The Number of quantitative measure of linearly independent paths through a program's source code is called as Cyclomatic Complexity ( if/ if else / for / while )

Cyclomatric complexity is a measure of how complex a unit of software is.It measures the number of different paths a program might follow with conditional logic constructs (If ,while,for,switch & cases etc....). If you will like to learn more about calculating it here is a wonderful youtube video you can watch https://www.youtube.com/watch?v=PlCGomvu-NM

It is important in designing test cases because it reveals the different paths or scenarios a program can take . "To have good testability and maintainability, McCabe recommends that no program module should exceed a cyclomatic complexity of 10"(Marsic,2012, p. 232).

Reference: Marsic., I. (2012, September). Software Engineering. Rutgers University. Retrieved from www.ece.rutgers.edu/~marsic/books/SE/book-SE_marsic.pdf