程序复杂度之圈复杂度

圈复杂度(Cyclomatic complexity)也称为条件复杂度或循环复杂度,是一种软件度量,是由Thomas J. McCabe, Sr. 在 1976 年提出,用来表示程序的复杂度,其符号为 VG 或是 M。圈复杂度是对源代码中线性独立路径数的定量测量。

圈复杂度使用的程序的控制流图来计算:在图中的节点对应于程序中一组不可分割的命令[代码行],有向边连接两个可连续执行的节点;[可连续执行的两个节点:第二个节点的命令组可能在第一个节点执行后立刻开始执行]。圈复杂度可以应用到独立的功能,模块,方法或类。

基础路径测试:通过测试用例测试程序中的每个线性无关的独立路径;在这种测试策略下,测试用例的数目将等于该程序的圈复杂度;

圈复杂度定义

圈复杂度度量的是程序中线性独立路径的数量;例如:如果程序中不包含控制、判断、条件语句(例如 if,swith 等),那么复杂度就是 1 ;因为整个程序只有一条执行路径;如果程序包含一条IF语句,那么就会有两条路径来执行完整个程序(IF为 TRUE,IF 为 FALSE),所以这时候的复杂度就是 2;两个嵌套的 IF 语句,或者包含两个判断条件的一个 IF 语句,复杂度就是 4;

在数学上,一个结构化程序的圈复杂度通过该程序的控制流图来定义;控制流图包含程序的基本块(图的节点),和两个基本块之间可执行性(图的边)。

原理:


上图:单程序的控制流图。此程序由红色的节点开始运行,然后进入循环(红色节点下由三个节点组成),离开循环后有条件分支,最后运行蓝色节点后结束,此控制流图中,E = 9, N = 8, P = 1,因此其圈复杂度为 9 - 8 + (2*1) = 3

数学表达式:

                    M = E - N + 2P

其中
E 为图中边的个数
N 为图中节点的个数
P 为连接组件的个数

强连通图的圈复杂度定义:要求做完线上功能的先要求线上的功能

上图:对应同一个程序的控制流图,但多加一个从结束点到启始点的边,因此为强连通的控制流图,若利用此图计算圈复杂度,其公式为 M=E-N+P,而 E = 10、N = 8、P = 1,因此圈复杂度为 3
另一个计算圈复杂度的公式用与计算每一个结束节点总是连接到启动节点的流程控制图;这种图称为强连通的;此时的圈复杂度就是图中回路的个数,也称为第一贝蒂数[first Betti number]),其公式如下:

                      M = E - N + P

上式可以视为计算图中线性独立回路(回路内不包括其他回路)的个数,由于控制流图增加结束点到启始点的边,因此对应一个结束点至少会有一个回路。
对于单一的程序(或副程序或方法),P 恒为 1。对于单一子程序,该公式可以简单的表达为:

                      M = E - N + 2

圈复杂度可以适用于同时分析许多程序或副程序的情形(例如针对一个类中的所有方法),此时 P 等于程序的个数,因为每一个程序的图都是一个独立的连接组件。若每一个程序都只一个结束点,P 也可以视为是结束点的个数。

McCache 证明了任何只有一个进入点和一个技术点的结构化程序,其圈复杂度等于程序中决策点(IF,FOR loops)的个数加 1;

圈复杂度也可以延伸到多个结束点的程序,此时的圈复杂度如下:

                       π - s + 2

其中
π 是程序中决策点的个数

s 为结束点的个数

圈复杂度应用

限制软件复杂度
麦凯布提出圈复杂度时,其原始目的之一就是希望在软件开发过程中就限制其复杂度。他建议程序设计者需计算其开发模块的复杂度,若一模块的圈复杂度超过 10,需再分区为更小的模块。NIST(国家标准技术研究所)的结构化测试方法论已此作法略作调整,在一些特定情形下,模块圈复杂度上限放宽到 15 会比较合适。此方法论也承认有些特殊情形下,模块的复杂度需要超过上述的上限,其建议为“模块的圈复杂度需在上限范围以内,否则需提供书面数据,说明为何此模块圈复杂度有必要超过上限。”

评估软件的结构化程度 「structuredness」
Essential complexity (numerical measure of "structuredness")

启示软件测试工作

圈复杂度决定了需要多少个测试用来达到特定模块测试覆盖率要求;

模块内聚性的评估
可以预期一个复杂度较高模块的内聚性会比较低,至少不会到功能内聚性的程度。一个有高复杂度及低内聚性的模块中会有许多的决策点,这类的模块多半运行超过一个明确定义的任务,因此内聚性较低。一个 2005 年的研究发现复杂度的度量和由专家评估的模块内聚性有高度负相关,反而针对内聚性设计的度量和专家评估结果之间的相关性还比较不明显[6]。

推测软件缺陷个数

许多研究指出一模块及方法的圈复杂度和其中的缺陷个数有相关性,许多这类研究发现圈复杂度和缺陷个数有高度的正相关:圈复杂度最高的模块及方法,其中的缺陷个数也最多。

不过,有些研究是在控制模块大小相近的情形下进行分析(例如比较二个源代码行数相近,但圈复杂度不同模块的缺陷个数),许多这类的研究发现圈复杂度和缺陷个数没有明显相关,不过仍有一些研究认为在此情形下二者仍有相关性。有些此领域的研究者认为那些研究结果圈复杂度和缺陷个数没有明显相关的研究,其研究方法的有效性可能有问题。

莱斯·哈顿认为利用圈复杂度来预测缺陷个数,和利用源代码行数来预测缺陷个数的结果大致相近。

OneAPM Mobile Insight 以真实用户体验为度量标准进行 Crash 分析,监控网络请求及网络错误,提升用户留存。访问 OneAPM 官方网站感受更多应用性能优化体验,想阅读更多技术文章,请访问 OneAPM 官方技术博客
本文转自 OneAPM 官方博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,473评论 25 707
  • 银行软件测试面试问题 软件测试经典面试题 软件测试面试题汇总 测试技术面试题 1、什么是兼容性测试?兼容性测试侧重...
    天宇逍遥heart阅读 1,436评论 0 20
  • 今天,天气晴朗,阳光明媚。奶奶说:今天咱们吃炖鸡。我盼了好久,从起床一直到中午,终于可以吃顿鸡了。 ...
    皓皓_f9d7阅读 289评论 0 0
  • 亲爱的珍姐: 展信佳! 给你写这封信不要觉得奇怪喔,只是把平时没有说的话说出来。在这些忙碌的日...
    Melodyhui阅读 178评论 0 1
  • 每个人都有自己的个性,不是别人的影子,可以改变自己,不能让自己迷失,人最可怕的就是找不到自己,从不想去改变自己,而...
    Ownery阅读 1,658评论 0 1