文献阅读笔记 # 面向大规模多版本软件系统的代码克隆检测加速技术

news2024/9/22 21:31:36
  • 面向大规模多版本软件系统的代码克隆检测加速技术,方维康 吴毅坚 赵文耘,《计算机应用与软件》复旦大学软件学院、复旦大学上海市数据科学重点实验室
  • 2022 April

面向大规模多版本软件系统的代码克隆检测加速技术

摘要

很多代码克隆检测方法主要针对软件系统的单个版本进行检测,在多版本情况下效率较低。本文提出一种针对多版本软件系统的克隆检测加速技术,可以快速得到每个版本的克隆情况。

通过版本间方法映射技术为不同版本代码内容高度相似的同一方法构建方法版本组,选取每个方法版本组中最早的版本作为样本方法,样本方法的集合构成历史映像,对历史映像进行克隆检测,同时建立样本方法和方法版本组间的方法索引。根据历史映像克隆检测结果及方法索引恢复原始的全量克隆关系。

结论:与文本对比方法提速4倍。
这里的多版本不是组件的多版本…是指被测软件具有多个版本…!!
ps:本文加速的重点不是克隆检测本身,而是如何处理多版本之间的重复代码,标记重复代码、减少查询量,去重后的集合叫历史映像

0 引言

  • 代码克隆普遍存在,代码克隆与程序的缺陷率、软件稳定性、软件质量、软件维护成本存在关联;
  • 传统的代码克隆检测在多版本时对每个版本挨个比较,计算量较大,没有充分利用同项目多版本之间的信息(版本更新变化的代码量只占总代码量中的小部分);

本文方法:方法版本组 => 样本方法 => 历史映像 => 克隆检测 => 版本恢复
关键技术:

  • 1.如何快速分析出系统所有版本中的每个方法;
  • 2.基于局部相似性比较在前后版本快速建立演化关系;
  • 3.基于索引快速恢复所有克隆关系;

1 代码克隆

Ⅰ型克隆: 除去空白符和注释之外完全一样的代码片段;
Ⅱ型克隆: 除了空白符、注释、标识符、类型和字面值有可能不同之外,语法结构上完全一致的代码片段;
Ⅲ型克隆:除了空白符、注释、标识符、类型和字面值有可能不同之外,还有可能添加、修改或删除了一些代码行的代码片段;
Ⅳ型克隆: 功能上一致但代码本身相似度较低的代码片段(语义级克隆);

  • 从Ⅰ型克隆到 Ⅲ 型克隆,克隆片段之间的语法相似度逐渐降低。Ⅳ 型在语法级别相似度已经很低。

  • 克隆对:存在克隆关系的两个代码片段被称为一组克隆对;
  • 克隆组(类):一组存在克隆关系的代码片段被称为克隆组;
  • 克隆实例:克隆对或克隆组中的每一个代码片段都称为一个克隆实例;
  • 方法级克隆:如果两个或多个方法是彼此克隆的,则将这种克隆称为方法级克隆。方法级克隆的克隆实例是完整的方法(即函数级克隆);

代码克隆检测基本思路:基于文本、基于 token、基于程序依赖图、基于抽象语法树、基于代码底层表示等;

  • 但上面的方法里,在大规模克隆检测(亿行级),只有 SourcererCC 和 SAGA 表现相对还行。
  • 考虑多版本的克隆检测:
    • 比如分析一个多版本项目的克隆演化图谱时,只分析目标项目最初版本的克隆检测结果,然后再用版本管理工具的修改信息追踪克隆;缺点:丢失最初版本后续版本的所有克隆(检测不出);【?为啥会检测不出,这个和增量克隆检测有啥区别
    • 增量克隆检测:缺点:不适用于跨项目克隆检测。【和上面有啥区别?跨项目是指最开始检测出的克隆组件结果里面根据增量在这个组件结果集合里去定位克隆部分,而不去查引入的新组件么?那如果放到所有组件库里去查不行吗?

本文相比增量检测,相当于是对增量也做了压缩,没有扫全部的增量,而是扫低于阈值的增量,对于轻微修改某函数是不会额外去检测的,但对于新创建的函数或者大幅修改逻辑会重新扫

2 基于版本间代码压缩的多版本克隆检测加速技术

2.1 项目信息预处理

目标项目集:所有待检测的项目的集合

  • 对目标项目进行预处理,括项目版本信息提取和项目方法信息提取
    • 版本信息提取:该项目所有发布版本的相关信息,包括每个版本的名称、发布时间、各个版本的代码,同时将该项目的各个版本按照发布时间先后进行组织排序;
    • 方法信息提取:对目标项目每个版本,方法提取器提取代码中所有方法的相关信息,其中根据该项目所使用的编程语言采用了相关的语法解析工具(例如 JavaParser、TXL 等)包括方法签名、方法完全限定名、方法所在文件的路径、方法起止行,最后将这些信息以方法为单位保存到一个集合中,将其称为该版本的方法信息集合

2.2 构建历史映像

历史映像:为不同版本中方法名及所属文件路径一致且代码内容相同或高度相似的同一方法( 下文简称为相同方法) 构建方法版本组。再选取每个方法版本组中最早的版本作为样本方法,样本方法的集合则称为历史映像

  • 方法版本组:方法映射器将含有多个版本的项目基于方法名及文件路径构建将不同版本、代码内容相同或高度相似的相同方法构建方法版本组。(不一定是完全一致,相似的方法/函数也作为一个方法版本组);
    • 规则: 版本按发布时间排序,对于每个方法,判断其是否已经属于某个方法版本组,否则新建一个组,对于该方法,提取其方法名与所在文件的相对路径,查找所有后续版本中与该相对路径、方法名都相同且文本高度相似的方法,将这些方法添加到该新的方法版本组。
    • 规则:相同方法判断依据:方法完全限定名相同/相似、方法所在的文件的路径一致且方法源代码间有非常高的文本相似度,本文采用最长公共子序列长度识别相似度。
      • 这种方式会导致方法移动、文件重命名的需要重新参与计算,但这个效率的损失相比不加路径限定考虑的代码带来的性能损失少很多。
  • 选择样本方法:本文统一选取所有方法版本组中最早的版本作为样本方法;

2.3 克隆检测

本文采用了 Saga;支持Ⅰ型到 Ⅲ 型克隆的检测;
Li G,Wu Y,Roy C K,et al. Saga: Efficient and largescale detection of near-miss clones with GPU acceleration [C]/ /2020 IEEE 27th International Conference on Software Analysis,Evolution and Reengineering ( SANER) . IEEE,2020: 272 - 283

2.4 恢复全量克隆关系

2.5 优化方案

方法版本组构建时用多线程对构建算法并行化改造,不同方法的版本组之间构建互不影响因此满足并行的前提。并行粒度(即线程池的核心数量)是 CPU 可用核数的两倍。

function FUNCVEGROUPCONSTRUCT(FuncInfoSetList)
	coreSize←availableProcessors( ) * 2
	exec←Executors.newFixedThreadPool(coreSzie)
	for currentVer∈AllVers do
		for currentFunc∈currentVers.getFuncInfoSet() do
			if currentFunc.isUnmarked() then
				currentFunc.mark()
				exec.submit(DetectSameFunc())
			end if
		end for
	end for
	exec.shutdown()
	return funcVerGroupMap
end function

function DETECTSAMEFUNC()
	for i from currentVer to lastVer do
		targetVer←FuncInfoSetList.get(i)
		if targetVer.getFuncInfoSet().contains(currentFunc) then
			targetFunc←targetVer.getFuncInfoSet().get(currentFunc)
			if getSimilarity(currentFunc, targetFunc) > threshold then
				funcVerGroupMap.get(currentFunc).add(targetFunc)
				targetFunction.mark()
			end if
		end if
	end for
end function

3 实验

设备:英特尔 i7-7820X 型 CPU(8 核心 16 线程), 32 GB 主存, 1 TB 固态存储硬盘, CentOS7 操作系统。
数据:github stars > 50, total 251 Java projects, date 2004~2019, 约 3 亿行。
结论:预处理后的查询量减少了87%,速度提升4倍。

4 结语

略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/377380.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

_Linux (网络版计算器简易实现)

文章目录1. 协议2. 网络版计算器简易实现代码链接3. 网络版计算器2-1. 约定的协议方案有两种2-3. 协议代码框架1. 自定义的协议方案2. json(库里的完整协议方案)2-4. send和recv单独使用不安全2-5. 剩余代码写法讲解参考如下:2-6. 代码运行结果示意图&am…

9.5 PIM-SM

实验目的 熟悉PIM-SM的应用场景掌握PIM-SM的配置方法 实验拓扑 实验拓扑如图9-40所示: 图9-40:PIM-SM 实验步骤 (1)配置IP地址 MCS1的配置 MCS1的配置如图9-41所示: 图9-41:配置MCS1的IP地址 R1的配置 …

VMware安装FreeBSD虚拟机

1. 下载FreeBSD镜像地址 国内阿里云下载地址: freebsd-releases-ISO-IMAGES安装包下载_开源镜像站-阿里云 选择自己需要的版本下载。 2. 创建FreeBSD虚拟机 2.1. 选择操作系统类型 2.2. 导入FreeBSD镜像 3. 安装FreeBSD 第1步:保持默认让其自动进入…

复习知识点十之方法的重载

目录 方法的重载 练习1: 练习1: 数组遍历 练习2: 数组的最大值 练习3: 练习4: 复制数组 基本数据类型和引用数据类型 方法的重载 Java虚拟机会通过参数的不同来区分同名的方法 练习1: public class Test4 {public static void main(String[] args) {//调用方法 // …

grid宫格布局新手快捷上手-f

前言 grid 网上有很多,但都是大而全的,感觉新人上手很吃力,本文仅以最快捷的方式进行介绍,如何使用grid宫格布局 本文是新人上手,若想了解更多grid布局,请阅读其他文章 使用 声明布局 display: grid;声…

springboot+pgbouncer+postgres数据库连接池集成方案及问题解决

期望通过每一次分享,让技术的门槛变低,落地更容易。 —— around 前言 旨在解决微服务项目全是连接池并影响数据库并发连接,作者的环境是基于sprongboot微服务连接postgres数据库,每个微服务的DAO层配置都使用了连接池技术。后续…

一个线程两次调用start()方法会出现什么情况?

第17讲 | 一个线程两次调用start()方法会出现什么情况? 今天我们来深入聊聊线程,相信大家对于线程这个概念都不陌生,它是 Java 并发的基础元素,理解、操纵、诊断线程是 Java 工程师的必修课,但是你真的掌握线程了吗&am…

如何编程实现从多数据库操作数据

对于数据量很大的复杂系统,有时候会采用分库或者分表的减轻单台数据库服务器压力,截止目前有一些工具直接支持读写分离等,例如ShardingSphere,如果不采用工具框架,从编码出发,如何实现从多个数据库读写数据…

FFmpeg 中的多线程解码

1.共享变量的互斥互斥锁(mutex-lock)是一种信号量,用来防止两个线程在同一时刻访问相同的共享资源,它有锁定状态和非锁定状态。在任意时刻,一个线程要想存取共享数据,线程必须首先获得mutex-lock&#xff0…

一种全新的图像变换理论的实验(四)——研究目的替代DCT和小波

一、前言 2023年02月28日凌晨1点 以前我定义为这个算法是滤波算法,实则上应该算是一种新变换算法,比如傅里叶变换(FFT)、离散余弦变换(DCT),以及小波变换。所以就把所有的标题改变了一下。 本次…

MySQL的InnoDB 三种行锁,SQL 语句加了哪些锁?

InnoDB 三种行锁: Record Lock(记录锁):锁住某一行记录 Gap Lock(间隙锁):锁住一段左开右开的区间 Next-key Lock(临键锁):锁住一段左开右闭的区间 哪些语句…

前端面试题 —— HTML

目录 一、src 和 href 的区别 二、对 HTML 语义化的理解 三、DOCTYPE(⽂档类型) 的作⽤ 四、script 标签中 defer 和 async 的区别 五、常⽤的 meta 标签有哪些? 六、HTML5 有哪些更新 八、行内元素有哪些?块级元素有哪些? 空(void)元素…

【正点原子FPGA连载】第十九章FreeRtos Hello World实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第十九章FreeRto…

项目调研丨以太坊再质押项目EigenLayer白皮书四大看点(内附完整版中文白皮书)

北京时间2月21日下午,被众多一线投研机构视为2023年以太坊最重要的创新,有可能开启以太坊新叙事方向的项目Eigenlayer终于披露了其第一版白皮书。EigenLayer是以太坊的再质押集,允许共识层ETH质押者选择验证构建在以太坊生态系统之上的新软件…

第七节 面向对象

面向对象 1.类和对象是什么? )类:是共同特征的描述(设计图);对象:是真实存在的具体实例。 2.如何设计类? public class 类名 { 1、成员变量(代表属性的,一般是名词) 2、成员方法(代表行为的,一般是动词) 3.如何创建对象? 类名对象名new 类名(); 4.拿到对象后怎么…

ubuntu 编译安装支持CUDA的OpenCV

安装须知 cuda支持 在安装完“ linux CUDAtoolkitcudnntensorrt 的安装”之后进行支持cuda的opencv安装 否则报错:CMake Error at modules/dnn/CMakeLists.txt:41 (message): DNN: CUDA backend requires CUDA Toolkit. Please resolve dependency or disable OPE…

Ubuntu 安装指定版本 Mysql,并设置远程连接(以安装mysql 5.5 为例)

目录 一、安装Mysql 1、卸载Mysql(可跳过) 2、安装mysql 软件源 3、安装mysql 5.5 4、验证测试 二、设置远程登录 1、允许使用root账号远程连接 2、Mysql 允许远程登录 一、安装Mysql 1、卸载Mysql(可跳过) 如果之前安装…

数据结构六大排序

1.插入排序 1.插入排序 思路: 从第一个元素开始认为是有序的,去一个元素tem从有序序列从后往前扫描,如果该元素大于tem,将该元素一刀下一位,循环步骤3知道找到有序序列中小于等于的元素将tem插入到该元素后&#xff0…

卡特兰数

文章目录1、简介1.1 何为卡特兰数1.2 卡特兰数的通项公式2、应用2.1 题目1:括号合法题目描述思路分析2.2 题目2:进出栈的方式2.2.1 题目描述2.2.2 思路分析2.3 题目3:合法的序列2.3.1 题目描述2.3.2 思路分析2.3.3 代码实现2.4 题目4&#xf…

分布式ID生成系统

目录背景常用分布式ID生成系统介绍UUIDSnowflake背景 在大多数复杂的分布式系统中,往往需要对大量的数据和消息进行唯一标识。而对分布式系统后台数据库的分库分表后需要有一个唯一的ID来表示一条数据或者是消息。那么我们分布式系统ID一般都有哪些需求呢&#xff1…