【问题标题】:Should LOC counting include tests and comments?LOC 计数是否应该包括测试和评论?
【发布时间】:2010-09-21 10:25:40
【问题描述】:

虽然 LOC(# 行代码)是衡量代码复杂性的一个有问题的衡量标准,但它是最流行的一种,如果使用得非常小心,至少可以粗略估计代码库的相对复杂性(即,如果一个程序是 10KLOC,另一个是 100KLOC,用相同的语言编写,由能力大致相同的团队编写,第二个程序几乎肯定要复杂得多)。

在计算代码行数时,您更喜欢计算 cmets in 吗?测试呢?

我已经看到了各种方法。 cloc 和 sloccount 等工具允许包含或排除 cmets。其他人认为 cmets 是代码的一部分及其复杂性。

单元测试也存在同样的困境,有时会达到被测代码本身的大小,甚至超过它。

我见过各种方法,从仅计算“可操作”非注释非空行到“XXX 行测试、注释代码”,这更像是在所有代码上运行“wc -l”项目中的文件”。

您的个人偏好是什么,为什么?

【问题讨论】:

    标签: metrics code-metrics


    【解决方案1】:

    一位智者曾经告诉我,在管理程序员时,“你得到你所衡量的”。

    如果您在其 LOC 输出中对它们进行惊人的评价,您往往会得到很多代码行。

    如果你根据他们解决的错误数量来评价他们,你会发现修复了很多错误。

    如果您根据添加的功能对它们进行评分,您会获得很多功能。

    如果你根据圈复杂度对它们进行评分,你会得到非常简单的函数。

    由于如今代码库的主要问题之一是它们的增长速度有多快,以及它们一旦增长就很难改变,我倾向于完全避免使用 LOC 作为衡量标准,因为它会推动错误的基本行为。

    也就是说,如果你必须使用它,算上没有 cmets 和测试,并且需要一致的编码风格。

    但是,如果您真的想要衡量“代码大小”,只需 tar.gz 代码库。与易受不同编程风格影响的计算行数相比,它往往可以更好地粗略估计“内容”。

    【讨论】:

    • 我想知道如果您在列表中添加“如果您按照客户满意度对他们进行评分,......”会得出什么结论。
    • 如果您按客户满意度对它们进行评分,您会得到非常大的费用报告。 ;)
    【解决方案2】:

    也必须维护测试和 cmets。如果您打算使用 LOC 作为指标(我只是假设我无法说服您放弃它),您应该给出所有三个(真实代码行、cmets、测试)。

    最重要(并且希望是显而易见的)事情是你要始终如一。不要报告一个项目只有几行真实代码,而另一个项目结合了这三行。查找或创建一个工具,为您自动执行此过程并生成报告。

    Lines of Code:       75,000
    Lines of Comments:   10,000
    Lines of Tests:      15,000
                      ---------
    Total:              100,000
    

    这样你就可以确定它会

    1. 完成。
    2. 每次都以相同的方式完成。

    【讨论】:

    • +1 用于维护推理。我自己从不使用 LoC 作为衡量标准,但每个月或两个管理层都会要求提供项目 LoC 计数。包括 cmets 和 tests 还有一个好处,就是将我的计数过程简化为 powershell 中的一行命令。 :)
    【解决方案3】:

    我个人认为 LOC 指标本身并不像其他一些代码指标那样有用。

    NDepend 将为您提供 LOC 度量,但也会为您提供许多其他度量,例如循环复杂度。这里没有列出所有这些,而是​​列表中的link

    还有一个免费的CodeMetric add-inReflector

    【讨论】:

      【解决方案4】:

      我不打算直接回答你的问题,原因很简单:我讨厌代码行数度量。无论您要测量什么,都很难做得比 LOC 更差;几乎任何其他你关心的指标都会变得更好。

      特别是,您似乎想要衡量代码的复杂性。总体而言,cyclometric complexity(也称为 McCabe 的复杂性)是更好的衡量标准。

      具有高循环复杂度的例程是您想要集中注意力的例程。正是这些例程难以测试、被 bug 腐烂至核心且难以维护。

      有许多工具可以衡量这种复杂性。用你最喜欢的语言在 Google 上快速搜索一下,就会发现很多工具都具有这种复杂性。

      【讨论】:

        【解决方案5】:

        代码行数 确切的意思是:不计算 cmets 或空行。为了使其与其他源代码具有可比性(无论其指标是否有用),您至少需要类似的编码风格:

        for (int i = 0; i < list.count; i++)
        {
            // do some stuff
        }
        
        for (int i = 0; i < list.count; i++){
            // do some stuff
        }
        

        第二个版本完全相同,但少了一个 LOC。当你有很多嵌套循环时,这可以总结很多。这就是为什么发明像function points 这样的指标的原因。

        【讨论】:

        • 用于此类分析的大多数工具都在测量逻辑代码行 (LLOC),这会将上述两个代码块的计数相同。
        【解决方案6】:

        取决于您使用 LOC 的目的。

        作为一种复杂性度量 - 不是那么多。也许 100KLOC 主要是从一个简单的表生成的代码,而 10KLOC 是 5KLOC 正则表达式。

        但是,我看到与运行成本相关的每一行代码。只要程序存在,您就需要为每一行付费:它需要在维护时读取,它可能包含需要修复的错误,它会增加编译时间、从源代码获取控制和备份时间,然后再进行更改或删除它,您可能需要确定是否有人依赖它等。平均成本可能是每行和每天几分钱,但这是加起来的东西。

        KLOC 可以作为项目需要多少基础设施的第一手指标。在这种情况下,我将包括 cmets 和测试——即使注释行的运行成本远低于第二个项目中的正则表达式之一。

        [编辑] [对代码大小有类似看法的人]1

        【讨论】:

          【解决方案7】:

          我们只使用代码行数来衡量一件事 - 一个函数应该包含足够少的代码行,无需滚动屏幕即可阅读。比这更大的函数通常很难阅读,即使它们的循环复杂度非常低。对于他的使用,我们确实计算了空格和 cmets。

          还可以很好地查看在重构期间您删除了的代码行数 - 在这里您只想计算实际的代码行数、不利于可读性的空格和 cmets没用的(不能自动化)。

          最后是免责声明 - 明智地使用指标。指标的一个很好的用途是帮助回答“代码的哪一部分将从重构中受益最多”或“最新签入的代码审查有多紧迫?”的问题。 - 一个圈复杂度为 50 的 1000 行函数是一个闪烁的霓虹灯,上面写着“现在重构我”。指标的错误用法是“程序员 X 的生产力如何”或“我的软件有多复杂”

          【讨论】:

            【解决方案8】:

            文章摘录:How do you count your number of Lines Of Code (LOC) ? 与计算 .NET 程序的逻辑 numbers of lines of code 的工具 NDepend 相关。


            如何计算代码行 (LOC) 的数量?

            你计算方法签名声明吗?你计算只有括号的行吗?当一个方法调用因为大量参数而写在多行时,您是否计算了几行?你计算“命名空间”和“使用命名空间”声明吗?你计算接口和抽象方法声明吗?您在声明字段分配时计算它们吗?你算空行吗?

            根据每个开发人员的编码风格和选择的语言(C#、VB.NET...),通过测量 LOC 可能会有显着差异。

            显然,通过解析源文件来测量 LOC 看起来像是一个复杂的主题。由于机敏,有一种简单的方法可以准确地测量所谓的逻辑 LOC。与物理 LOC(从解析源文件推断的 LOC)相比,逻辑 LOC 有 2 个显着优势:

            • 编码风格不会干扰逻辑 LOC。例如,LOC 不会更改,因为由于参数数量过多,方法调用会在多行中产生。
            • 逻辑 LOC 独立于语言。从用不同语言编写的程序集中获得的值具有可比性并且可以相加。

            在 .NET 世界中,逻辑 LOC 可以从 PDB 文件中计算出来,这些文件被调试器用来链接 IL 代码和源代码。工具 NDepend 以这种方式计算方法的逻辑 LOC:它等于在 PDB 文件中为方法找到的序列点的数量。序列点用于标记 IL 代码中对应于原始源中特定位置的点。有关序列点的更多信息在这里。请注意,对应于 C# 大括号‘{’和‘}’的序列点不被考虑在内。

            显然,类型的 LOC 是其方法的 LOC 之和,命名空间的 LOC 是其类型的 LOC 之和,程序集的 LOC 是其命名空间的 LOC 和应用程序是其程序集 LOC 的总和。以下是一些观察:

            • 接口、抽象方法和枚举的 LOC 等于 0。计算 LOC 时只考虑有效执行的具体代码。
            • 命名空间、类型、字段和方法声明不被视为代码行,因为它们没有对应的序列点。
            • 当 C# 或 VB.NET 编译器面临内联实例字段初始化时,它会为每个实例构造函数生成一个序列点(同样的注释适用于内联静态字段初始化和静态构造函数)。
            • 从匿名方法计算的 LOC 不会干扰其外部声明方法的 LOC。
            • NbILInstructions 和 LOC(在 C# 和 VB.NET 中)之间的总体比率通常在 7 左右。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-09-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多