大家知道单元测试对代码质量的保障作用已经没什么可说的了。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. 使用Java Servlet进行简单登录

    效果图 登录页面代码:login.html <%@ page language="java" contentType="text/html; charset=UTF ...

  2. JavaScript数据结构-19.拓扑排序

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. JavaScript设计模式-10.工厂模式实例xhr

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. 【angular5项目积累总结】遇到的一些问题以及解决办法

    1.项目中字符串特别是\r\n,替换成br之后,在页面换行无法生效? 答:绑定元素 innerHTML. <div class="panel-body" [innerHTML ...

  5. yii2 页面加载警告框

    在视图页面代码如下 <?php use kartik\alert\Alert; echo Alert::widget([ 'type' => Alert::TYPE_INFO, 'titl ...

  6. python——高级特性(2)

    迭代 在python中迭代是通过for ....in...完成的,只要是可迭代对象都可以迭代 #!usr/bin/python #-*- coding:UTF-8 -*- #tuple迭代 t=[(1 ...

  7. Core.Java.Volume.I.Fundamentals.10th.Edition 14.5.8 Volatile域 中文版 章节勘误

    今天重扫了corejava 14 并发的一章,在谈到volatile域代替synchronized 应用于并发更新时,看到如下内容,并发更新可用内部锁的方式但会带来阻塞问题,可用volatile域替代 ...

  8. linux ubuntu 学习总结(day01)基本命令学习

    个人总结,请尊重版权,转载请在显眼地方注明出处:https://www.cnblogs.com/sunshine5683/p/9948259.html day(01)基本命令学习 今天开始自学linu ...

  9. SqlServer之一些小问题

    如何用变量代替字段名? 将语句赋给一个varchar 变量,下列语句等价于(假设传进去的@id=’name‘):'select  name from 表名' 如果直接执行这个语句,是没用的.@id不会 ...

  10. Oracle查看表空间容量

    select /*+ no_merge */ al.tablespace_name, round(al.currsizemb) currsizemb, round(al.maxsizemb) maxs ...