【问题标题】:How to calculate cyclomatic complexity of a project (not a class/function)?如何计算项目的圈复杂度(不是类/函数)?
【发布时间】:2012-11-26 19:23:04
【问题描述】:

如何计算整个Java项目的cyclomatic complexity?我对每种方法都有复杂性,但是如何将它们全部聚合成一个数字指标?有什么想法或现有的方法吗?

我不是在寻找工具,而是在寻找算法。

简单的平均很难奏效,因为有许多1-complexity 方法,它们的复杂性并不低,但对代码库的重要性不高(在大多数情况下)。

【问题讨论】:

    标签: java cyclomatic-complexity


    【解决方案1】:

    整本书都是关于代码指标的,所以你很幸运,你问的是一个更具体的问题。对于 Java 圈复杂度,您可以找到超过圈复杂度 5 或 6 的方法数量(您可以在此处选择数字)。如果这个数字超过你的方法数量的一定百分比,那么整体圈复杂度很差。一个好的百分比数字完全取决于项目的大小,所以也许不是只除以方法的数量,您可以通过使其在大数字时缓慢增长来减轻方法计数的权重,例如一个平方根或对数,以尝试使其随着项目的增长而更加稳定。

    可能是这样的:

    public double evaluateCyclomaticComplexity(List<MethodStat> methodStats) {
        int bad = 0;
        for (MethodStat methodStat : methodStats)
            if (methodStat.getCyclomaticComplexity() >= 6)
                bad++;
    
        double denominator = Math.sqrt(methodStats.size());
        return bad * 100.0 / denominator;
    }
    

    这里返回的数字越小越好。对于真正糟糕的项目,这将返回大于 100 的值。

    分母函数应该代表随着代码库的增长,复杂性增长的速度有多快。通常,您希望随着代码的增长而降低每个函数的 CC 以使其保持可维护性,因此最好随着项目规模的增加而增长缓慢。

    对其进行测试、调整等。最终,代码指标很难做到恰到好处,在阅读了几篇关于开源软件的期刊论文后,我可以证明这一点,这些论文使用数字表示“可维护性”。如果花足够的时间,我们可以在这里提出的任何事情都可能会得到很大的改进。

    【讨论】:

      【解决方案2】:

      我找到了那个公式:

      TCC = Sum(CC) - Count(CC) + 1
      TCC: Total CC
      Sum(CC): Sum of CC of all functions
      Count(CC): Number of functions
      

      来源:http://www.aivosto.com/project/help/pm-complexity.html

      但也许它太有限了。

      另一个想法是将程序的调用图视为程序本身并计算调用图的CC。节点将由它们的 CC 加权。 (我不知道是否可行,这只是一个想法)

      【讨论】:

        【解决方案3】:

        我不知道这是否会有所帮助,但我只是想说出我的想法。您可以使用全局深度计数器来获取方法调用深度并在每次方法调用时更新它。 您会看到这里的每个方法都手动注入了相同的 sn-p,但可能有一种解决方案可以将代码自动注入所有方法。我认为,通过堆栈跟踪长度的级别,您可以计算聚合复杂度。

        public class Cyclomatic
        {
            public static int max = Integer.MIN_VALUE;
        
            static void a() 
            {
                b();
                int temp = Thread.currentThread().getStackTrace().length;
                if (temp > max)
                    max = temp;
            }
        
            static void b() 
            {
                c();
                int temp = Thread.currentThread().getStackTrace().length;
                if (temp > max)
                    max = temp;
            }
        
            static void c() 
            {
                int temp = Thread.currentThread().getStackTrace().length;
                if (temp > max)
                    max = temp;
            }
        
            public static void main(String[] args) 
            {
                a();
                System.out.println(max);
            }
        }
        

        输出:

        5
        

        【讨论】:

          【解决方案4】:

          据我所知,您的问题还没有答案。但是 Microsoft Visual Studio 正在做的是总结给定项目的所有圈复杂度,并将结果视为汇编级别的圈复杂度。但我个人会建议你使用 Max Cyclomatic Complexity。只需简单地将最大圈复杂度视为项目圈复杂度。这样做的原因是,只要项目中有一种具有更高循环复杂度的方法,那么项目就会成为您的软件系统的瓶颈。另一个原因是由于强连通图论,根据 McCabe 的原论文 Cyclomatic Complexity for a strong connected graph is the maximum Cyclomatic Complexity between Cyclomatic Complexities within独立存在的电路。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-20
            • 1970-01-01
            • 2023-03-27
            • 1970-01-01
            • 2018-02-22
            • 1970-01-01
            • 2011-10-04
            • 1970-01-01
            相关资源
            最近更新 更多