源代码行数

源代码行数（Source lines of code）简称SLOC，也称为程式行数（lines of code），简称LOC，是由计算程式源代码的行数来估计计算机程序大小的软件度量。源代码行数一般会用来预计开发程式需要的人力及时间，若在软件完成后，也可以用来估计程式开发生产力或可维护性。

## 计算方式

许多软件上的比较都只和专案中源代码行数的数量级有关。用源代码行数来比较10,000行源代码和100,000行源代码的专案，会比比较20,000行和21,000行的专案要有效很多。有关源代码行数的计算方式仍有许多不同意见，不过源代码行数的数量级可以做为软件复杂度及评估需要人时的一个指标。

源代码行数计算方式主要可分为两种：实体源代码行数（physical SLOC、LOC）及逻辑源代码行数（logical SLOC、LLOC）。这两种计算方式的具体定义也有很多种，不过最常用的实体源代码行数是直接计算不考虑注解时，程式码的行数。

逻辑源代码行数设法计算可执行的“叙述”的数量。但具体定义和使用的程式语言有关（若是针对类似C语言的编程语言，有一种逻辑源代码行数的方式就是计算程式码结尾的分号个数）。要制作工具来计算实体源代码行数比较容易，也比较容易说明其定义。不过实体源代码行数会受到一些和逻辑无关的格式及程式风格影响，逻辑源代码行数比较不会受到格式及程式风格影响。在实务上，计算源代码行数时不一定会具体写出其定义，而逻辑源代码行数和实体源代码行数之间会有显著的差异。

以下的C语言程式可以用来说明计算源代码行数的模糊不清之处：

```c
for (i = 0; i < 100; i++) printf("hello"); /* How many lines of code is this? */
```

上例中有：

- 1行的实体源代码行数（LOC）,
- 2行的逻辑源代码行数（LLOC）（For循环及printf指令）
- 1行注解

依照程式设计者及程式设计风格的不同，上述一行实体源代码行数的程式可以写成以下多行的程式：

```c
/* Now how many lines of code is this? */
for (i = 0; i < 100; i++)
{
    printf("hello");
}
```

此例中有

- 4行的实体源代码行数（LOC）：但放括号的工时需要估计进来吗？
- 2行的逻辑源代码行数（LLOC）：看不到重排非叙述程式码的影响
- 1行注解

甚至是“实体”及“逻辑”的源代码行数都有许多不同的定义。罗伯特·E·帕克（在他还在软件工程研究所时）等人开发了定义SLOC值的一个框架，让人可以谨慎的说明及定义其专案中用到的SLOC定义及量测方式。例如，大部分软件会有代码复用，在回报量测结果时，如何决定是否要包括代码复用内容就很重要。

## 起源

人们刚开始用源代码行数来量度软件长度时，当时最常用的语言（像是Fortran及汇编语言）都是行导向的程式语言。当时打孔卡是输入程式的主要方式。一张打孔卡对应一行程式，打孔卡是一张一张的，要计算数量很方便。打孔卡也是程式开发者有形的产出，因此管理者利用计算打孔卡数量来计算程式开发者的生产力是相当合理的。现今最常使用的程式语言在格式上的限制不多，一行的字元数也不止是80个字或是96个字，而一行的文字不一定对应一行的程式码。

## 源代码行数的计算方式

用源代码行数来做为程式相关属性的量度，有些会有些争议。根据多次的实验，已确认源代码行数和开发者所花的工作量高度相关，SLOC越大的程式，开发需要花费的时间及工作量也比较多，因此SLOC若用来估计开发者花的心力，是相当有效的。不过SLOC和机能的相关性很低，熟练的程式设计者可能可以用较少的程式码达到相同的机能，因此有可能SLOC较短的程式，其机能甚至有可能比（其他程序员所写）SLOC较长的程式还要多。用SLOC来度量程式设计者的生产力不一定合适，因为有可能程序员只用少少几行程式，达到的机能比其他程序员的许多行程式更多（其他程序员也花了较多的心力）。好的程式设计者会将有重复程式的模组整合成一个模组，提升了程式的品质，但以SLOC的角度来看，反而让SLOC减少了。而且，有经验的程式设计者往往会负责最困难的模组，因此看起来不像其他程式设计者一样的“有生产力”。甚至，没有经验的程式设计者往往会有代码重复的情形，一般而言不鼓励代码重复，因为很不容易维护，很容易有错，但是会有较多的SLOC。

若用SLOC比较不同程式语言写的程式，除非有针对不同语言的特性进行正规化，不然其准确度就更低了。各种的计算机语言都设法在简洁及清楚这两方面来取舍，有些强调简洁，有些则强调清楚。以极端的例子来说，汇编语言会需要上百行的程式，来完成APL语言几个字即可完成的工作。以下是C语言及COBOL所写的Hello World范例程式的比较：

C｜COBOL

```c
#include <stdio.h>

int main() {
    printf("Hello world\n");
}
```

```text
      identification division.
      program-id. hello .
      procedure division.
      display "hello world"
      goback .
      end program hello .
```

源代码行数：4（不算空白）｜源代码行数：6（不算空白）

在使用SLOC来计算程式设计者的努力时，另一个常见的问题是人工写的程式以及自动产生程式的差异。许多现代的软件工具都可以在鼠标点选一些设定，或是摆放物件之后，自动生成一大段的程式。例如只要将一些图案移到工作区，图形使用者界面产生器就会自动产生对应控件的大量程式。这个工作量完全不能和写设备驱动程式的工作量相比。但两者产生的程式码长度可能差异不大，这也是用SLOC来计算的缺点。

目前有许多成本、时程及工作量估计的模型，会用SLOC为输入引数，包括巴里·勃姆等人建立，广为使用的构造性成本模型（COCOMO）、PRICE系统、True S及Galorath的SEER-SEM。这些模型的预测能力都很好，但程度会和给模型的输入资料（尤其是SLOC估计值）准确程度有关。有些软件工程研究者建议用功能点代替SLOC，不过因为功能点和SLOC高度相关，而且无法自动计算，因为各研究者对此论点的看法还没有共识。

### 举例

依照Vincent Maraia的统计，微软 Windows NT中不同时期的操作系统其SLOC如下：

年份｜操作系统｜SLOC（百万）

1993｜Windows NT 3.1｜4–5

1994｜Windows NT 3.5｜7–8

1996｜Windows NT 4.0｜11–12

2000｜Windows 2000｜29以上

2001｜Windows XP｜45

2003｜Windows Server 2003｜50

针对Debian2.2版（Windows NT）以后的操作系统，也有类似的统计，Debian GNU/Linux 2.2有55 million SLOC，依传统私用程式的开发方式，需要14,005人年，需要花190亿美金。

年份｜操作系统｜SLOC（百万）

2000｜Debian 2.2｜55–59

2002｜Debian 3.0｜104

2005｜Debian 3.1｜215

2007｜Debian 4.0｜283

2009｜Debian 5.0｜324

2012｜Debian 7.0｜419

## 评论

### 优点

- 可以自动化计算：因为源代码行数是程式的实体特质，可以用计算行数的程式来取代人工的行数计算。有许多小的程式可以计算软件的源代码行数，不过因为各语言的语法及结构特性不同，针对一种语言计算逻辑源代码行数的程式可能无法计算其他语言的逻辑源代码行数。若是要计算实体源代码行数，已有可以适用于数十种语言的软件。
- 符合直觉的度量：源代码行数是符合直觉的软件度量标准，易于计算。也有研究者认为用功能点来度量软件，不过功能点不是程式的实体特质，是逻辑上的概念。而源代码行数没有这类问题，就算是经历不多的程序员也可以用源代码行数来量测软件大小。
- 无所不在的度量方式：自从软件开发的最早期开始，就已经出现源代码行数的计算。因此，可以说，源代码行数的资料会比其他软件度量方式的资料会多很多。

### 缺点

- 无法反映实际的工作量。用源代码行数来计算软件开发的生产力，有些基本层面的问题。有些研究者认为不能只用编写程式阶段产生的成果来估算专案的产出，一般而言，编写程式阶段只占整体的30%至35%。
- 缺乏有关功能凝聚力的资讯：软件开发者付出的心力可能和源代码行数的相关性较高，但其程式的机能性和源代码行数的关系较小。有经验的程式设计者可以用较短的程式码达到相同的功能。甚至，一些较熟练的软件开发者，会用重构的方式，设计调整程式，去除多余的程式，程式会变的较精简，也比较理想，但以源代码行数来看，看不到这方面的贡献。
- 心理学上的问题：若程式设计者的产出是用源代码行数来估算，难免他会调整程式写法，让相同机能的程式可以有较多行数的源代码。

在公共广播电视公司的记录片《Triumph of the Nerds》中，微软的执行长史蒂夫·巴尔默曾评论过计算源代码行数的作法：

在IBM里有一种软件中的文化，是要计算K-LOC，K-LOC就是一千行程式。专案有多大？这个专案大约是10K-LOC的专案，这个人是写20K-LOC程式的人，这个程式码有50K-LOC。IBM想要调整这种有关K-LOC以及员工薪资的作法。我们在OS/2上面花费了多少钱，也就是他们工作可换来的钱。你写了多少K-LOC的程式？我们设法说服程式设计者，若开发者有好的想法，让一个程式可以不需要20K-LOC的程式码，只要4K-LOC的程式码就可以达到相同目的，为什么我们应该要少付一点钱？就因为他让程式变的更小又更快了？让K-LOC减少了？这是我们的方法论。

## 相关名词

- KLOC ˈ KAY：一千行程式码
- KDLOC：一千行已交付的程式码
- KSLOC：一千行源代码
- MLOC：一百万行程式码
- GLOC：十亿行程式码

## 外部链接

- Definitions of Practical Source Lines of Code Resource Standard Metrics (RSM) defines "effective lines of code" as a realistics code metric independent of programming style.
- Effective Lines of Code eLOC Metrics for popular Open Source Software Linux Kernel 2.6.17, Firefox, Apache HTTPD, MySQL, PHP using RSM.
- Tanenbaum, Andrew S. Modern Operating Systems (2nd ed.). Prentice Hall. .
- C. M. Lott: Metrics collection tools for C and C++ Source Code
- Folklore.org: Macintosh Stories: -2000 Lines Of Code