「代码当量」指标解读看这一篇就够了

本文详细介绍了代码当量(ELOC)的概念、计算原理和相较于代码行数的优势。代码当量基于抽象语法树复杂度,不受编程习惯影响,能更好地反映逻辑量。计算过程包括解析源代码为AST,计算树差异,加权总和得到代码当量。相比于代码行数,代码当量更能准确量化开发工作量,不受格式更改、代码移动等因素干扰。

本文正文内容约1700字,建议阅读时间:4分钟。

阅读本文你将收获:

1、什么是代码当量,原理是什么?

2、代码当量的计算公式是什么?

3、相比代码行数,代码当量好在哪?

前言

代码当量也即是开发当量(英文名为ELOC,Equivalent Line of Code,)下文称”代码当量”,由思码逸原创,是一种对开发者代码工作量进行合理量化和度量的指标。与代码行数、提交数等浅层工作量指标相比,代码当量(开发当量)的优势体现在两个方面:不易受到编程习惯或特定代码行为的干扰(如换行、空行、注释、括号等),且能更好地反映代码开发所涉及的逻辑量

看到这里你可能还是一头雾水:代码当量的原理是什么?它如何排除噪音的干扰?它的科学性到底如何?希望这篇文章能够帮助你初步了解代码当量和它背后的故事

01 代码当量从哪来,计算原理是什么?

软件开发是一个动态的过程,代码随着提交发生变化,相应的抽象语法树也会演变。代码当量指标正是基于抽象语法树复杂度的计算。这一指标的原型来自思码逸创始团队2018年在软件工程顶级会议 FSE 上发布的论文《关于量化代码贡献的开发价值》

计算代码当量时,我们既可以计算绝对值,也可以计算累积值:

- 代码当量的绝对值,可以理解为对代码在一个提交切面上的抽象语法树进行计算,会考虑抽象语法树的节点数、不同节点的权重等。

- 代码当量的累积值,则是计算代码在每一次提交前后的变化,并累加。针对某一次提交而言,其代码当量的计算是基于提交前后的抽象语法树之间的最小编辑距离。在思码逸的算法设计中,代码删减也被视为贡献,只是权重会显著低于代码增加。

代码当量的绝对值随着开发过程而上下浮动,通常呈现“持续增加—小幅回落”的模式并不断重复;而代码当量的累积值单调递增,主要用于反映团队或项目的产出和进度。

02 如何计算某个提交的代码当量?

计算原理算法图示

下图简单演示了这个过程如何从代码的修改计算出代码当量的数值。

代码当量计算原理算法图示

首先,将源代码解析为抽象语法树(AST),AST是源代码抽象语法结构的树型表示。它的“抽象”性质有助于消除测量中不重要的噪音,这个特性可以在以下的例子中体现。

代码修改前后的抽象语法树对比

其次,计算新旧树之间的树的差异(树diff)。树diff步骤的输出是一个编辑脚本,由一系列编辑操作组成,正是这些操作一步步将旧AST转换成新AST。编辑操作分为四种类型:插入、删除、移动和更新。例如,插入操作可以将新节点作为AST中现有节点的子节点插入;更新操作可以更新现有节点的值。

最后,我们计算所有编辑操作的加权总和,根据编辑操作的类型和此编辑操作的AST节点的类型为每个操作分配权重,最终得到代码当量的数值。

总结:从源码到代码当量的基础计算过程如下,一共分三步:

1. 将旧/新源代码解析为ASTs

2. 通过在旧/新ASTs之间进行树状转换来生成编辑脚本

3. 从编辑脚本加权计算代码当量

03 相比代码行数,代码当量好在哪?

担心一个例子不过瘾,我们一口气举了四个例子。

例1

代码行数指标(LOC,Line of Code)很容易被简单的代码习惯差异所影响

在下图中,我们删除红色代码,新增绿色代码,实质上只是简单的代码格式变动,并不实际改变基本逻辑和代码质量,却表现为1行添加和4行删除(总共5行更改)。

相比之下,由于纯句法变化对AST没有影响,此段代码的新旧ASTs是相同的,所以这个操作的代码当量为0。

例2

代码行数不擅长检测代码块的移动

比如下面的代码变动,简单地交换类中函数的顺序会产生4行添加和4行删除。

但是从抽象语法树的角度,这次修改只是改变了myMethod()函数对应节点在其父节点下的顺序,该节点本身未发生任何修改。因此修改myMethod()的代码当量为0。

例3

代码行数无法区分不同性质的代码的工作量

考察以下Python代码,它的功能是在给定的字典中找到对称对。测试数据test_dict和实际功能函数find_sym_pairs()贡献了相等数量的行数(7行),这当然不能反映编写这两段代码所付出的不同的工作量。

但是通过为每个AST节点类型分配不同的权重,我们可以对不同类型AST节点的编辑操作进行更合理的评估,更合理的量化开发过程中的工作量。

例4

一个真实的案例:Bitcoin 项目中一个名为 Fix CRLF 的提交,修改了62个文件,删除了32876行代码,又将这32876行加了回去。

从代码行数的角度看,这是一个体量相当巨大的修改,但实际上对代码没有任何改动。这个提交的代码当量为0。

想试试代码当量计算?

我们近期上线了代码当量游乐场,一款交互式的简版代码当量体验工具。你可以在游乐场中任意选择语言、调整加权设置、亲手修改代码,体验不同的代码编辑行为所产生的代码当量(开发当量)。

代码当量游乐场界面

### 集成思码逸工具至 Spring Boot 项目 为了在 Spring Boot 项目中集成思码逸 (Semmle) 工具来进行代码量统计,需遵循一系列配置流程。值得注意的是,思码逸主要用于静态代码分析而非直接用于代码量统计;然而,通过其强大的查询功能可间接实现这一目的。 #### 准备工作 安装思码逸环境:访问官方文档获取最新的安装指南并完成本地或服务器端部署[^1]。 确保已有 Spring Boot 开发环境,包括但不限于 JDK、Maven 或 Gradle 构建工具以及 IDE 支持。 #### 创建 CodeQL 数据库 CodeQL 是由 Semmle 提供的一种强大查询语言,可用于编写自定义查询来提取有关源代码的信息。对于想要统计特定类型的文件数量或者行数的情况,可以通过创建针对目标仓库的 CodeQL 数据库开始: ```bash codeql database create myproject-db --language=java -s /path/to/springboot/project ``` 此命令会基于指定路径下的 Java 项目构建一个新的 CodeQL 数据库实例[^2]。 #### 编写 Query 文件 利用 CodeQL 查询语法编写专门用来计算总行数或其他度量指标的 .ql 脚本文件。下面是一个简单的例子,它能返回整个项目内的所有 `.java` 文件及其对应的物理行数: ```sql import java from File f where f.getExtension() = "java" select f.getName(), f.getSize() ``` 保存上述内容到 `count_lines.ql` 文件内,并将其放置于适当位置以便后续执行。 #### 执行 Queries 并解析结果 一旦准备好所需的 queries 后,则可通过 CLI 命令行工具运行这些查询并将输出重定向给 JSON 格式的文件: ```bash codeql query run count_lines.ql --database=myproject-db --format=json -o results.json ``` 最后一步是从生成的结果集中读取数据并汇总得到最终统计数据。这通常涉及到一些额外的数据处理逻辑,在某些情况下可能还需要开发小型的应用程序片段来辅助完成这项任务。 #### 结合 Spring Boot 实现自动化报告生成功能 为了让这个过程更加便捷高效,可以在 Spring Boot 应用内部封装 RESTful API 接口,允许外部调用触发自动化的代码质量评估与统计报表生产服务。具体做法是在控制器层面上设计相应的 HTTP 请求处理器函数,负责接收参数输入、调用底层业务逻辑组件直至响应客户端请求为止。 ```java @RestController @RequestMapping("/api/code-metric") public class CodeMetricController { @Autowired private CodeAnalysisService codeAnalysisService; @GetMapping("/stats") public ResponseEntity<Map<String, Object>> getCodeStatistics(@RequestParam String repoPath){ Map<String,Object> result = this.codeAnalysisService.analyze(repoPath); return new ResponseEntity<>(result, HttpStatus.OK); } } ``` 以上就是关于如何在 Spring Boot 中集成思码逸进行代码量统计的大致介绍。需要注意的是实际应用场景可能会有所不同,因此建议根据具体情况调整实施方案细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值