【发布时间】:2012-08-23 12:48:36
【问题描述】:
根据圈复杂度的基本规则,下面代码的复杂度应该是2(只有一个分支点——for循环)。
function SumArray(array_to_sum) {
var sum = 0;
for (var i = 0; i < array_to_sum.length; i++) {
sum += array_to_sum[i];
}
return sum;
}
很多现代框架等都提供了数据映射功能,比如jQuery.each()或者Underscore.js框架中的大部分方法。考虑以下代码:
function SumArray(array_to_sum) {
var sum = 0;
jQuery.each(array_to_sum, function(index, value) {
sum += value;
});
return sum;
}
按照圈复杂度的典型规则,第二个例子的CC度量为1。工作完全一样,函数的人为复杂度根本没有改变。我所做的只是将一种循环数据的方式换成另一种循环数据的方式。
同样考虑这个人为的例子,我们将原始函数的内部封装在一个自调用闭包中,为外部方法生成 1 的圈复杂度,而实际上并未改变方法的工作方式:
function SumArray(array_to_sum) {
return (function() {
var sum = 0;
for (var i = 0; i < array_to_sum.length; i++) {
sum += array_to_sum[i];
}
return sum;
})();
}
圈复杂度的真正度量是否应该包括对数据映射/归约方法的考虑,例如jQuery.each(),尤其是在使用匿名局部闭包时?
也许闭包应该将其复杂性导出到关闭的父级。此外,也许一般方法应该能够定义一个导出复杂度,该复杂度添加到调用它的任何函数的复杂度中 - 例如,jQuery.each() 的导出复杂度应该为 1,以便使用它代替正常的循环计数复杂度相同。
【问题讨论】:
-
你的问题到底是什么?
-
我不明白为什么您的第二个示例的代码复杂度为 1。程序可以采用循环(每个)路径,也可以不采用。不应该还是2吗?
-
@Steven “圈复杂度的真正度量是否应该包括数据映射/归约方法,例如 jQuery.each()?”
-
@SplinterOfChaos 因为调用其他函数不会增加圈复杂度的度量。
jQuery.each()是一个函数调用,尽管它基本上是循环的简写。我觉得这应该会增加 CC,但不是按标准衡量的。 -
CC 计数的大多数度量
for-each与for相同。一个程序总体上有一个 CC,但是很难从它的整体 CC 度量中对一个程序说太多,因为这个气球非常迅速,相反,我们检查单个可测试单元(如函数)并考虑该方法的 CC - 通常试图保持不到 10 岁。
标签: unit-testing complexity-theory cyclomatic-complexity