文档章节

重复代码-数据分析

开源中国驻成都办事处
 开源中国驻成都办事处
发布于 2014/03/26 12:27
字数 1366
阅读 143
收藏 0
点赞 0
评论 0

《重复代码检测-背景、方法与工具》一文中,已经谈到了重复代码产生的原因,以及检测重复代码的一些方法和工具。这篇文章我们尝试来分析一下检测工具出具的报告。因为检测工具出具的报告主要包括重复代码的位置,并没有一下统计的信息。无论从项目整体考虑的角度,还是给老大们的报告的角度,我们都需要一些整理后的数据,最好是图表,可以直观地看出代码的一些问题。

这里我们以Simian为例来进行分析。Simian是一个基于字符串的重复代码检测工具。特点是基本无限制地支持所有语言,速度非常快。Simian的安装参考<A title=http://www.harukizaemon.com/simian/installation.html href="http://www.harukizaemon.com/simian/installation.html">http://www.harukizaemon.com/simian/installation.html。在VS中安装Simian插件,参考http://www.dotblogs.com.tw/hatelove/archive/2011/12/07/how-to-find-duplicate-code-by-simian.aspx。它还支持Ant、InteliJ。如果你对二次开发感兴趣,可以基于其提供的Java接口进行更多的定制开发。

我们这里简单介绍一下:

Simian的命令行参数-formatter可以指定输出的格式。为了方便后面的处理,我们让它生成xml格式的文件(-formatter=xml)。结构化的文件使用正则表达式+Perl脚本很容易处理。

-threshold可以指定检测重复代码的标准。只有大于等于这个数字的重复代码行才会被视为是重复代码。

开启-reportDuplicateText参数可以输入重复的代码段,这样子非常直观的可以在输出报告中就看到重复的代码。

通过文件匹配符。比如**/*.cpp,就是文件夹下所有cpp文件,包括所有的子文件夹。

加上需要的参数(E:\Software\simian-2.3.35\bin\simian-2.3.35.exe -formatter=xml -reportDuplicateText -balanceSquareBrackets -balanceParentheses E:\Software\simian-2.3.35\bin\test.cpp > E:\Software\simian-2.3.35\bin\test.xml),执行出来的结果可能类似于:

test.cpp

TiXmlString operator - (const char* a, const TiXmlString & b) 
{ 
    TiXmlString tmp; 
    TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) ); 
    tmp.reserve(a_len + b.length()); 
    tmp.append(a, a_len); 
    tmp += b; 
    return tmp; 
}
TiXmlString operator + (const char* a, const TiXmlString & b) 
{ 
    TiXmlString tmp; 
    TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) ); 
    tmp.reserve(a_len + b.length()); 
    tmp.append(a, a_len); 
    tmp += b; 
    return tmp; 
}

test.xml

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet href="simian.xsl" type="text/xsl"?> 
<simian version="2.3.35"> 
    <check balanceParentheses="true" balanceSquareBrackets="true" failOnDuplication="true" ignoreCharacterCase="true" ignoreCurlyBraces="true" ignoreIdentifierCase="true" ignoreModifiers="true" ignoreStringCase="true" reportDuplicateText="true" threshold="6"> 
        <set lineCount="6"> 
            <block sourceFile="E:\Software\simian-2.3.35\bin\test.cpp" startLineNumber="13" endLineNumber="18"/> 
            <block sourceFile="E:\Software\simian-2.3.35\bin\test.cpp" startLineNumber="3" endLineNumber="8"/> 
            <text> 
<![CDATA[    TiXmlString tmp;    TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) ); 
    tmp.reserve(a_len + b.length()); 
    tmp.append(a, a_len); 
    tmp += b; 
    return tmp; 
]]> 
            </text> 
        </set> 
        <summary duplicateFileCount="1" duplicateLineCount="12" duplicateBlockCount="2" totalFileCount="1" totalRawLineCount="20" totalSignificantLineCount="14" processingTime="686"/> 
    </check> 
</simian>

XML的最后给出了一个总结报告。里面的duplicateLineCount和duplicateBlockCount比较难理解。特别是存在多余两个代码块重复,并且重复的行数不一样的时候,如果你对Simian的计算机制有兴趣,可以写一些例子尝试下。我们只能推测它的计算方法,因为Simian并不开源。

从这个报告中,可以看到一些信息:

1. <set lineCount="6">…</set>表示了重复的代码段有多少行。它是大于等于我们设置的threshold的。

2. <block sourceFile="file" startLineNumber="n" endLineNumber="m"/>表示了重复代码所在的文件,以及重复代码开始和结束的行号。

3. duplicateLineCount表示了总共有多少重复的代码行。上面的例子,我们计算一些重复代码所占的比率duplicateLineCount/totalSignificantLineCount=12/14=85.71%。直观的感觉有点偏大。的确是这样,在真正的项目代码上,由于存在一块代码满足不同threshold的重复的时候,会计算过多的代码行,进而导致重复代码所占的比率偏高。这个数据虽然可以解释,但是很容易让人迷糊。我们可以考虑把它作为衡量重复代码的一个标准,但需要大家都理解背后的计算原理。

信息1给我们一个启示,我们可以统一每个lineCount下有多少个重复的Block。直观地感受,应该是lineCount越大,重复的Block数目应该越小,因为程序员不大可能写出重复很多行的代码;lineCount越小,重复的Block数目应该越多,因为这种重复的可能性越高。我绘制了一个项目的数据图:

面对上面的数据,我们希望横轴不能再增加,不能出现新的重复代码块,或者更大的重复代码块。纵轴上,我们希望不会再增加。

信息2给了我们重复代码位于哪些文件当中。而文件肯定是属于某个Component的,因此我们分析每个Component中重复的代码。单位可以是行数,也可以是块数。我绘制了一个项目的数据图:
上面的数据,如果Component的重复高,我们就要反思是不是出现了代码腐化,是不是修改的时候欠缺考虑。

通过这些数据,我们希望看到的是代码存在的问题。价值不在于找到我们重构的地方,而在与我们开始量化重复代码,及代码的质量。有了量化的标准后,我们就可以追踪代码质量的变化,进而避免恶化腐化的发生。

© 著作权归作者所有

共有 人打赏支持
开源中国驻成都办事处
粉丝 84
博文 286
码字总数 335913
作品 0
成都
程序员
外媒调查:GitHub上的海量代码都是Copy的

  【IT168 资讯】 GitHub是一个可以代码共享的平台,因此网站上一定数量的重复代码是可以理解的。然而,最近的研究表明,GitHub上有超过70%的代码都是重复的。本次调查中,Java在原创性上赢...

it168网站 ⋅ 2017/11/27 ⋅ 0

Java 集合类图

有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否 否 HashSet TreeSet 是(用二叉树排序) Map AbstractMap 否 使用key-value来映射和存储数据,Key必须惟一,value可...

MR_White ⋅ 2014/09/09 ⋅ 0

python求职Top10城市,来看看是否有你所在的城市

前言 从智联招聘爬取相关信息后,我们关心的是如何对内容进行分析,获取用用的信息。 本次以上篇文章“5分钟掌握智联招聘网站爬取并保存到MongoDB数据库”中爬取的数据为基础,分析关键词为“...

lemon ⋅ 2017/05/23 ⋅ 0

重复计算研究的十条简单规则

注:个人能力有限,解释未必得当,若有错误请见谅。 文献来源:Ten Simple Rules for Reproducible Computational Research 我们在这里提出针对计算分析研究重复性的十条简单规则。这些规则的...

王诗翔 ⋅ 2017/12/19 ⋅ 0

elasticsearch java api导入数据重复问题

问题如下: 我想用elasticseach java api实现定时导入mysql中的数据到es,遇到的问题是相同数据会出现重复导入的情况,我初步分析原因是id字段是又es自动生成的,即使是相同数据也会生成不同...

kardelsharpeye ⋅ 2014/10/11 ⋅ 4

一个多线程bug引发的测试思考

背景 今天收到测试的一个bug反馈,bug描述:author表中存在重复的作者信息,在提测时我有说明task解析页面后获得作者信息会按authorId 判断DB中是否已经存在,存在了则不往DB中插入,这本是一...

测试开发栈 ⋅ 06/04 ⋅ 0

基于Redis计数器的并发请求去重方案

缘起 业务逻辑为M服务器向中央服务器C上报数据,每条数据使用uid标识,即M服务器-->uid数据-->C服务器。基于超时重发机制,M服务器可能会向C服务器发送重复数据,故C服务器需要做去重处理。 ...

爱做梦的胖子 ⋅ 2017/07/21 ⋅ 0

培训讲义--Coding质量的评定标准(01_03)

关于培训中的第二部分,针对Coding的一下问题作出的讲义PPT. Coding的常见问题 1)代码命名随意,不按照开发规范进行 变量名作用不清晰。 函数与过程的作用说明不足 2)代码逻辑凌乱 代码没有按...

技术小甜 ⋅ 2017/11/17 ⋅ 0

在pandas的unstack时报ValueError: duplicate entries 错误

pandas是python中用于数据分析和处理的一个基于numpy的基本库工具,是从事python语言数据领域的一个基本入门工具,常见用途有: a提供高级的数据结构和相当丰富的数据操作API b提高了对复杂矩...

良思远行 ⋅ 04/14 ⋅ 0

平台架构中性动态分析--PANDA

PANDA 是一个开源的平台架构中性动态分析。它是建立在QEMU全系统模拟器,所以分析获得所有代码执行客人和所有数据。PANDA 提供添加记录和回放执行的能力,提供整个系统深入迭代分析。此外,回放...

红薯 ⋅ 2015/01/05 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

UI ,前端框架选型

Flat-UI

miaojiangmin ⋅ 8分钟前 ⋅ 0

Istio Service Mesh 教程

Istio Service Mesh 教程 作者 宋净超 | 5400字 | 阅读大约需要11分钟 | 归档于istio | 发表于 2018-05-22 标签 #Istio #教程,来自 https://servicemesher.github.io/blog/istio-service-m...

openthings ⋅ 13分钟前 ⋅ 0

scala swing

scala swing组件的库 https://github.com/scala/scala-swing scala swing的API文档 https://www.scala-lang.org/api/2.9.1/scala/swing/package.html...

whoisliang ⋅ 17分钟前 ⋅ 0

CentOS安装配置Nginx

安装依赖 yum install gcc yum install pcre-devel yum install zlib zlib-devel yum install openssl openssl-devel //一键安装上面四个依赖 yum -y install gcc zlib zlib-devel pcre-deve......

临江仙卜算子 ⋅ 23分钟前 ⋅ 0

开源 java CMS - FreeCMS2.8 依申请公开

项目地址:http://www.freeteam.cn/ 依申请公开 1. 转交申请公开 用户可以把申请公开转交给其他人办理,系统会记录此申请公开的转交记录。 注意:同时只能转交一个申请公开。 选择需要转交的...

freeteam ⋅ 28分钟前 ⋅ 0

以太坊 web3.py 签名转账

以太坊 web3.py 签名转账 本文节选自电子书《Netkiller Blockchain 手札》 Netkiller Blockchain 手札 Mr. Neo Chan, 陈景峯(BG7NYT) 中国广东省深圳市龙华新区民治街道溪山美地 518131 +86...

netkiller- ⋅ 33分钟前 ⋅ 0

年薪40W的程序员必会的技术有哪些?

很多人在问我,程序员如何拿高薪,如何做到年薪40W+,其实总结出来还是一句话,你的技术决定你的能力已经薪资。 那么什么样的技术人才才能拿到一份Java行业里面的高薪呢? 下面是我的一个总结...

码代码的小司机 ⋅ 34分钟前 ⋅ 0

jesque-spring使用及源码分析

1.使用 jesque结合spring使用,步骤如下: 1.1 在项目中添加maven依赖 <dependency> <groupId>net.lariverosc</groupId> <artifactId>jesque-spring</artifactId> <version>1.0.0</ve......

Funcy1122 ⋅ 35分钟前 ⋅ 0

OSChina 周二乱弹 —— 加班的代码不要枉费了我的童子功

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《29》- 未完成乐队 《29》- 未完成乐队 手机党少年们想听歌,请使劲儿戳(这里) @FalconChen :#看球提醒# 02:00 巴西v...

小小编辑 ⋅ 今天 ⋅ 16

Docker Swarm的前世今生

概述 在我的《Docker Swarm集群初探》一文中,我们实际体验了Docker Swarm容器集群技术的魅力,与《Kubernetes实践录》一文中提到的Kubernetes集群技术相比,Docker Swarm没有Kubernetes显得...

CodeSheep ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部