4

根据圈复杂度的基本规则,以下代码的复杂度应为 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,以便使用它代替正常循环计数复杂度相同.

4

2 回答 2

1

圈复杂度是代码可读性的度量。McCabe 部分描述了测量圈复杂度的前提,“此外,复杂的组件也难以理解、难以测试和难以修改。”

即对读者来说复杂的代码更容易出现错误,因为它更难测试(通过单个代码块的更多路径。它可能会留下错误,因为很难修改,因为他们更难理解,所以人们避免修改它。

于 2012-08-26T14:10:06.830 回答
-2

圈复杂度的真正度量是否应该包括对数据映射/减少方法的考虑,例如 jQuery.each() 尤其是在使用匿名本地闭包时?

是的。当然。任何。

但请记住,“圈复杂度”是人为的;它只是我们给特定启发式算法家族的一个名称,用于估计特定代码的“复杂性”。如果您碰巧正在为 jQuery(或任何其他支持 lambda 的语言)设计一个圈复杂度审计工具,那么是的,一个特例 forjQuery.each()将是一个很好的功能,并让用户定义他们的“导出复杂度”自己的功能将是一个更好的功能。但是,让我们不要被关于这是计算圈复杂度的最真实方法的浮夸语言冲昏了头脑。这只是启发式的改进。我可以再给你十个可能的改进。

于 2012-08-26T04:45:37.727 回答