大家知道单元测试对代码质量的保障作用已经没什么可说的了。Microbenchmark(微基准测试)也是保证代码质量的重要手段,也是容易忽略的,它用来衡量一些小的代码片段的性能指标,完善的Microbenchmark可以便于定位出一些性能瓶颈,它类似于单元测试,能够进行持续集成,当代码有改动时能够通过持续集成的历史数据 看出对性能的影响点。

之前使用Google的Caliper,但目前还在重度开发中,每个版本API变化比较大,还有好些地方不够稳定,所以暂时放弃使用。

JUnitBenchmark

这里先重点介绍一下JUnitBenchmark的实践,它使用简单,有直观的图表。

例子:

添加依赖:

   <dependency>
<groupId>com.carrotsearch</groupId>
<artifactId>junit-benchmarks</artifactId>
<scope>test</scope>
<version>0.7.0</version>
</dependency>

@BenchmarkMethodChart(filePrefix = "target/PinyinConvertersBenchmark")  //指定报表的路径和文件名前缀
@BenchmarkHistoryChart(filePrefix = "target/PinyinConvertersBenchmark-history", labelWith = LabelType.CUSTOM_KEY, maxRuns = 20) //设置历史数据报表参数
public class PinyinConvertersBenchmark extends AbstractBenchmark {
final static Random random = new Random(); final static HanyuPinyinOutputFormat hanyuPinyinOutputFormat = SimplePinyinConverter.getInstance()
.getDefaultPinyinFormat()
.getPinyin4jOutputFormat(); @AfterClass
public static void after() {
CachedPinyinConverter cachedPinyinConverter = (CachedPinyinConverter) PinyinConverterFactory.CACHED_DEFAULT.get();
cachedPinyinConverter.dumpCacheInfo(System.out);
CachedConvertAccess.clear(cachedPinyinConverter);
} //总共运行20w次+5次热身
@Test
@BenchmarkOptions(benchmarkRounds = 200000, warmupRounds = 5, clock = Clock.NANO_TIME)
public void pinyinConverters_ConvertOneStr_CN() throws ConverterException {
PinyinConverters.toPinyin("我们对发动过", "");
} @Test
@BenchmarkOptions(benchmarkRounds = 200000, warmupRounds = 5, clock = Clock.NANO_TIME)
public void pinyin4j_ConvertOneStr_CN() throws BadHanyuPinyinOutputFormatCombination {
PinyinHelper.toHanyuPinyinString("我们对发动过", hanyuPinyinOutputFormat, "");
} //100个线程运行
@Test
@BenchmarkOptions(benchmarkRounds = 200000, warmupRounds = 5, concurrency = 100, clock = Clock.NANO_TIME)
public void testPutOne_100Thread_CN() {
testPutOne_OneThread_CN();
}
}

然后作为普通单元测试运行就可以了。

如果需要生产报表,

1. 要添加jvm参数运行,-Djub.consumers=CONSOLE,H2 -Djub.db.file=./target/.benchmarks

jub.db.file路径自己定义。

2. 还需要添加H2的依赖:

    <dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.170</version>
<scope>test</scope>
</dependency>

运行后在指定的报表目录下可以找到类似的html报表,对比了总次数、耗时、每个方法的运行时间、gc次数和耗时等数据:

不足之处

JUnitBenchmark也存在一些不足,报表和功能还不够丰富,只能做一些简单的微基准;使用并发测试时(例如设置concurrency = 100)经常会出现失败,已经反馈了bug,作者表示会尽快修复;

目前还没有现成的jenkins集成插件。但是JUnitBenchmark还只是alpha阶段,做到这样已经不错了。

其他Microbenchmark框架

以下记录一些Microbenchmark框架,不作详细介绍,有兴趣的慢慢去研究选择适合自己的。

jmh

ORACLE出品

http://assylias.wordpress.com/2013/05/06/java-micro-benchmark-with-jmh-and-netbeans/

https://github.com/nitsanw/jmh-samples

Japex

需要xml配置,初看配置有点复杂,但图表完善。

https://japex.java.net/docs/manual.html

Benchmarking framework

http://www.ellipticgroup.com/misc/projectLibrary.zip

Create quick/reliable benchmark with java

not parameterizable; Java library; JVM micro benchmarking; no plotting; no persistence; no trend analysis; statistics.

Commons monitoring

not parameterizable!?; Java library; no JVM micro benchmarking!?; plotting; persistence through a servlet; no trend analysis!?; no statistics!?.

Supports AOP instrumentation.

JAMon

not parameterizable; Java library; no JVM micro benchmarking; plotting, persistence and trend analysis with additional tools (Jarep or JMX); statistics.

Good monitoring, intertwined with log4j, data can also be programmatically accessed or queried and your program can take actions on the results.

Java Simon

not parameterizable!?; Java library; no JVM micro benchmarking; plotting only with Jarep; persistence only with JMX; no trend analysis; no statistics!?.

Competitor of Jamon, supports a hierarchy of monitors.

JETM

not parameterizable; Java library; JVM micro benchmarking; plotting; persistence; no trend analysis; no statistics.

Nice lightweight monitoring tool, no dependencies :) Does not offer sufficient statistics (no standard deviation), and extending the plugIn correspondingly looks quite difficult (Aggregators and Aggregates only have fixed getters for min, max and average).

junitperf

Mainly for doing trend analysis for performance (with the JUnit test decorator TimedTest) and scalability (with the JUnit test decorator LoadTest).

parameterizable; Java library; no JVM micro benchmarking; no plotting; no persistence; no statistics.

perf4j

not parameterizable; Java library; no JVM micro benchmarking; plotting; persistence via JMX; trend analysis via a log4j appender; statistics.

Builds upon a logging framework, can use AOP.

关于Java Microbenchmark的一点记录的更多相关文章

  1. JAVA 中LinkedHashMap要点记录

    JAVA 中LinkedHashMap要点记录 构造函数中可能出现的几个参数说明如下: 1.initialCapacity 初始容量大小,使用无参构造方法时,此值默认是16 2.loadFactor ...

  2. 关于Java8:StreamAPI的一点记录

    关于 Stream ,Functional Interface 的一点记录 stream对于集合操作的便捷度提升: import java.util.ArrayList; import java.ut ...

  3. Java学习-007-Log4J 日志记录配置文件详解及实例源代码

    此文主要讲述在初学 Java 时,常用的 Log4J 日志记录配置文件详解及实例源代码整理.希望能对初学 Java 编程的亲们有所帮助.若有不足之处,敬请大神指正,不胜感激!源代码测试通过日期为:20 ...

  4. 对Integer类中的私有IntegerCache缓存类的一点记录

    对Integer类中的私有IntegerCache缓存类的一点记录 // Integer类有内部缓存,存贮着-128 到 127. // 所以,每个使用这些数字的变量都指向同一个缓存数据 // 因此可 ...

  5. Java NIO学习与记录(八): Reactor两种多线程模型的实现

    Reactor两种多线程模型的实现 注:本篇文章例子基于上一篇进行:Java NIO学习与记录(七): Reactor单线程模型的实现 紧接着上篇Reactor单线程模型的例子来,假设Handler的 ...

  6. 转:五年java人的一点感悟

    转自:五年java人的一点感悟 恍然间,发现自己在这个行业里已经摸爬滚打了五年了,原以为自 己就凭已有的项目经验和工作经历怎么着也应该算得上是一个业内比较资历的人士了,但是今年在换工作的过程中却遭到了 ...

  7. Java给各个方法记录执行时间

    Java给各个方法记录执行时间 long startTime = System.currentTimeMillis();...//要测试时间的方法LoggerFactory.getLogger(Bas ...

  8. 从symbol link和hard link 到 unlink函数的一点记录

    之前一直对Linux的文件类型中的 “l” 类型的了解不是很深入,最近经过“圣经”指点,略知一二,在此先记录一下,以便以后查阅,之后会对文件和目录.文件I/O这部分再扩充. 首先需明确,Unix在查阅 ...

  9. 在java中使用JMH(Java Microbenchmark Harness)做性能测试

    文章目录 使用JMH做性能测试 BenchmarkMode Fork和Warmup State和Scope 在java中使用JMH(Java Microbenchmark Harness)做性能测试 ...

随机推荐

  1. postgresql客户端连接错误的解决方法【转】

    今天在重新设置postgresql服务器以后却发现启动不了服务器.错误如下:psql: could not connect to server: No such file or directory   ...

  2. [Xamarin] 產生專案的AndroidManifest.xml (转帖)

    紀錄一下 Xamarin 如何開啟 AndroidManifest.xml,因為這跟權限有關係,每個Android App幾乎都要設定 每次都想Add File 去增加但是其實是不對的 工具上面不管是 ...

  3. 数据库主键ID生成策略

    前言: 系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,下面介绍一些常见的ID生成策略. Sequence ID UUID GUID COMB Snowflake 最开始的自增ID为了实现分库 ...

  4. 深入分析java web技术内幕目录一览

    Web请求过程 如何发起请求:browser,httpclient http解析:chrome ,cache Dns域名解析:域名缓存 cdn:负载,动态加速,回源 Java I/O I/0类库的基本 ...

  5. AutoDetectChangesEnabled及AddRange解决EF插入的性能问题

    转自:http://www.cnblogs.com/nianming/archive/2013/06/07/3123103.html#2699851 记录下. 园友莱布尼茨写了一篇<Entity ...

  6. 使用 DL4J 训练中文词向量

    目录 使用 DL4J 训练中文词向量 1 预处理 2 训练 3 调用 附录 - maven 依赖 使用 DL4J 训练中文词向量 1 预处理 对中文语料的预处理,主要包括:分词.去停用词以及一些根据实 ...

  7. Betriebssystem

    1.Prozess 1.1 Das Begriff Der Prozess ist eine Entität der Aktivität,umfasst aktuell Aktivitäten,dur ...

  8. 动态rem解决移动前端适配

    背景 移动前端适配一直困扰很多人,我自己也是从最初的媒体查询,到后来的百分比,再到padding-top这种奇巧淫技,再到css3新单位vw这种过渡转变 但这些都或多或少会有些问题,直到使用了动态re ...

  9. 获取服务器时间ajax

    $.ajax({ type:"OPTIONS", url:"/", complete:function(x){ // alert(x.getResponseHe ...

  10. DataGridView 获取当前单元格

    获取DataGridview控件中的当前单元格,是通过DataGridview的Rows属性和Column属性的索引来取得的,他们的索引都是从0开始的. Private void datagridvi ...