14

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

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

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

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

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

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

4

8 回答 8

20

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

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

如果您根据他们关闭的错误数量对他们进行评分,那么令人惊讶的是,您会修复很多错误。

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

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

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

也就是说,如果您必须使用它,请计算无评论和测试,并且需要一致的编码风格。

但是,如果您真的想要衡量“代码大小”,只需 tar.gz 代码库。它倾向于作为对“内容”的更好粗略估计,而不是计算易受不同编程风格影响的行数。

于 2008-11-08T10:50:17.103 回答
9

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

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

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

这样你就可以确定它会

  1. 完成。
  2. 每次都以同样的方式完成。
于 2008-11-08T12:49:58.140 回答
2

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

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

Reflector还有一个免费的CodeMetric插件

于 2008-11-08T10:11:26.463 回答
1

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

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

具有高循环复杂度的例程是您想要集中注意力的例程。正是这些例程难以测试,因漏洞而腐烂到核心并且难以维护。

有许多工具可以测量这种复杂性。用你最喜欢的语言在谷歌上快速搜索一下,就会发现有几十种工具可以实现这种复杂性。

于 2008-11-08T10:15:42.353 回答
1

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

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

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

第二个版本完全相同,但少了一个 LOC。当你有很多嵌套循环时,这可以总结很多。这就是发明功能点等指标的原因。

于 2008-11-08T10:23:24.740 回答
0

取决于您使用 LOC 的目的。

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

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

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

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

于 2008-11-08T13:22:05.627 回答
0

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

看看你在重构过程中删除了多少行代码也很不错——在这里你只想计算实际的代码行数、不利于可读性的空格和无用的注释(不能自动化)。

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

于 2009-08-20T18:18:59.807 回答
0

文章摘录:如何计算代码行数 (LOC) ?相对于计算.NET 程序的逻辑代码行数的工具 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 的总和。以下是一些观察:

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