圈复杂度是什么?衡量一段代码有多“绕”的指标
TL;DR圈复杂度(Cyclomatic Complexity)是 Thomas McCabe 在 1976 年提出的软件度量指标,通过计算程序控制流图中独立路径的数量来衡量代码的复杂程度,数值越高,代码越难理解、测试和维护。
圈复杂度(Cyclomatic Complexity)是衡量程序复杂程度的经典软件度量指标,由 Thomas J. McCabe Sr. 在 1976 年提出,论文《一种复杂度度量》发表在《IEEE 软件工程汇刊》上,是软件工程领域的经典之作。
它衡量什么
直观地说,圈复杂度衡量的是一段代码里有多少条不同的执行路径。一段从头到尾直接执行、没有任何分支的代码,圈复杂度是 1;每多一个 if 判断、一个循环、一个 switch 的分支,或者一个“与”“或”条件,就多出一条可能的执行路径,圈复杂度随之增加。路径越多,代码的逻辑越“绕”,越难理解,也越容易藏着错误。
怎么计算
McCabe 用图论来定义它:把程序画成控制流图,每个基本代码块是一个节点,代码块之间可能的跳转是边。圈复杂度等于边数减去节点数再加 2(对于单个函数)。更简单的算法是:数出代码中判断条件的数量,再加 1。比如一个函数里有两个 if 和一个 for 循环,圈复杂度大约是 4。
有什么用
评估可维护性:圈复杂度高的函数,通常意味着逻辑过于复杂、职责太多,难以阅读和修改。McCabe 建议单个函数的圈复杂度不超过 10,很多团队把它作为代码规范的一部分,超过阈值就要考虑拆分函数。指导测试:圈复杂度给出了覆盖所有独立路径所需的最少测试用例数量,帮助评估测试是否充分。识别风险:研究和实践都表明,圈复杂度高的代码往往缺陷更多。如今,SonarQube 等代码质量工具和很多代码检查工具都会自动计算圈复杂度。
它也有局限:它只关心分支的数量,不反映代码在其他方面的复杂性,比如嵌套的深度、变量的复杂程度,因此常和认知复杂度等其他指标一起使用。在 AI 生成代码越来越多的今天,这类指标也被用来评估 AI 写出的代码质量。