使用JMH對比BeanUtils和BeanCopier

背景

許多時候須要對比不一樣的框架或工具或算法, 選擇使用性能更優的那一個。一般的作法是html

long start = System.currentTimeMillis();
for(int i=0; i<size; i++){
    doSomeWork();
}
long end = System.currentTimeMillis();
System.out.println("took time : "+(end-start));

但這樣的作法很是不嚴謹, 由於當獨立頻繁運行這一小塊代碼時,Jvm可能會針對性的作一些優化工做, 而在實際的生產環境中是不會有此優化的。 如一個Jvm優化的例子java

原始代碼git

int a = 1;
        int b = 2;
        int sum = a + b;

        return sum;

可能直接優化爲github

return 3;

因此最好使用更嚴謹的工具 來進行benchmark的工做,算法

Microbenchmarkings tools are intended to bring the JVM in "stable" state prior to executing tests and run your test suite for sufficient amount of time to get statistically proven evidence of the results.
摘自:http://www.buzdin.lv/2011/01/...框架

jmh就是這麼一個工具ide

JMH is short for Java Microbenchmark Harness. JMH is a toolkit that helps you implement Java microbenchmarks correctly. JMH is developed by the same people who implement the Java virtual machine, so these guys know what they are doing.工具

jmh使用示例

使用jmh來對比BeanUtils和BeanCopier性能

代碼優化

@State(Scope.Thread)
public class CopyPropertiesBenchmark {
  
    private UserModel model = new UserModel();
    private BeanCopier beanCopier = BeanCopier.create(UserModel.class, UserVo.class, false);

    /**
     * 人工setter複製屬性
     *
     * @return
     */
    @Benchmark
    public UserVo manuallySetter() {
        UserVo vo = new UserVo();
        vo.setAvatar(model.getAvatar());
        vo.setNick(model.getNick());
        // ...

        return vo;
    }

    @Benchmark
    public UserVo beanUitls() {
        UserVo vo = new UserVo();
        BeanUtils.copyProperties(this.model, vo);
        return vo;
    }

    @Benchmark
    public UserVo beanCopier() {
        UserVo vo = new UserVo();
        beanCopier.copy(this.model, vo, null);
        return vo;
    }
}

運行結果

# JMH 1.14.1 (released 5 days ago)
# VM version: JDK 1.8.0_91, VM 25.91-b14
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home/jre/bin/java
# VM options: -server
# Warmup: 5 iterations, 1 s each
# Measurement: 5 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.zhugw.CopyPropertiesBenchmark.beanCopier

# Run progress: 0.00% complete, ETA 00:00:30
# Fork: 1 of 1
# Warmup Iteration   1: 70737107.801 ops/s
# Warmup Iteration   2: 63704495.294 ops/s
# Warmup Iteration   3: 112706026.910 ops/s
# Warmup Iteration   4: 113979995.875 ops/s
# Warmup Iteration   5: 114595368.349 ops/s
Iteration   1: 113207053.036 ops/s
Iteration   2: 111641520.705 ops/s
Iteration   3: 111258060.492 ops/s
Iteration   4: 110293317.399 ops/s
Iteration   5: 110773170.278 ops/s


Result "beanCopier":
  111434624.382 ±(99.9%) 4285987.844 ops/s [Average]
  (min, avg, max) = (110293317.399, 111434624.382, 113207053.036), stdev = 1113057.432
  CI (99.9%): [107148636.538, 115720612.226] (assumes normal distribution)

...

# Run complete. Total time: 00:00:32

Benchmark                                Mode  Cnt          Score          Error  Units
CopyPropertiesBenchmark.beanCopier      thrpt    5  111434624.382 ±  4285987.844  ops/s
CopyPropertiesBenchmark.beanUitls       thrpt    5    2451858.127 ±   525264.183  ops/s
CopyPropertiesBenchmark.manuallySetter  thrpt    5  103524264.901 ± 17644747.083  ops/s

從上面的結果可知BeanCopier的性能優於BeanUtils, 吞吐量差距約爲45倍。

參考文檔

http://tutorials.jenkov.com/j...
http://nitschinger.at/Using-J...
http://hg.openjdk.java.net/co...

相關文章
相關標籤/搜索