文档章节

重复代码-数据分析

开源中国驻成都办事处
 开源中国驻成都办事处
发布于 2014/03/26 12:27
字数 1366
阅读 156
收藏 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
博文 287
码字总数 335913
作品 0
成都
程序员
外媒调查:GitHub上的海量代码都是Copy的

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

it168网站
2017/11/27
0
0
python求职Top10城市,来看看是否有你所在的城市

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

lemon
2017/05/23
0
0
解析、查找数组中重复出现的元素(Java)

 解析、查找数组中重复出现的元素,Java实现。 《数据结构与算法分析:解析、查找数组中重复出现的元素》 问题描述:一个结构化数据,假设事先按照某种顺序排好序(比如升序)的一个数组...

开开心心过
2015/08/05
0
0
elasticsearch java api导入数据重复问题

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

kardelsharpeye
2014/10/11
3.2K
4
重复计算研究的十条简单规则

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

王诗翔
2017/12/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

搬瓦工镜像站bwh1.net被DNS污染,国内打不开搬瓦工官网

今天下午(2018年10月17日),继搬瓦工主域名bandwagonhost.com被污染后,这个国内的镜像地址bwh1.net也被墙了。那么目前应该怎么访问搬瓦工官网呢? 消息来源:搬瓦工优惠网->搬瓦工镜像站b...

flyzy2005
50分钟前
1
0
SpringBoot自动配置

本篇介绍下,如何通过springboot的自动配置,将公司项目内的依赖jar,不需要扫描路径,依赖jar的情况下,就能将jar内配置了@configuration注解的类,创建到IOC里面 介绍下开发环境 JDK版本1.8 spr...

贺小五
今天
3
0
命令行新建Maven多项目

参考地址 # DgroupId 可以理解为包名# DartifactId 可以理解为项目名mvn archetype:generate -DgroupId=cn.modfun -DartifactId=scaffold -DarchetypeArtifactId=maven-archetype-quickst......

阿白
今天
1
0
OSChina 周四乱弹 —— 上帝对我单身年限的惩罚越来越长了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @达尔文:分享张卫健的单曲《身体健康》 《身体健康》- 张卫健 手机党少年们想听歌,请使劲儿戳(这里) 昨天是重阳节咯, 可惜小小编辑总是晚...

小小编辑
今天
12
1
django rest framework 外键序列化方法与问题总结

django rest framework 外键序列化方法与问题总结 当借口中需要出现一对多关系的时候,我们可以用rest_framwork的序列化功能来处理,代码如下. # models.pyfrom django.db import modelscl...

_Change_
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部