Bean属性拷贝性能分析

在 Java 系统工程开发过程中,都会有各个层之间的对象转换,比如 VO、DTO、PO、VO等,如果都是手动get、set又太浪费时间,还可能操作错误,所以选择一个转换工具会更加方便。

Posted by guanyang on 2023-05-12
Words 859 and Reading Time 4 Minutes
Viewed Times

前言

  • 在 Java 系统工程开发过程中,都会有各个层之间的对象转换,比如 VO、DTO、PO、VO等。
  • 如果都是手动get、set又太浪费时间,还可能操作错误,所以选择一个转换工具会更加方便。
  • 整理出常见属性转换工具如下
类型 实现原理 说明
getSetBeanCopy 原始赋值 基于getset方法进行属性转换
fastJsonBeanCopy json序列化反序列化 基于fastjson进行属性转换
apacheBeanCopy 反射 基于apache BeanUtils进行属性转换
springBeanCopy 反射 基于spring BeanUtils进行属性转换
beanMappingBeanCopy 属性拷贝 基于bean-mapping进行属性转换
beanAsmBeanCopy 字节码增强 基于bean-mapping-asm进行属性转换
beanCopierBeanCopy cglib生成get、set 基于BeanCopier进行属性转换
orikaBeanCopy 字节码增强 基于Orika进行属性转换
dozerBeanCopy 属性映射 基于Dozer进行属性转换
modelMapperBeanCopy 基于字节码框架ASM实现 基于ModelMapper进行属性转换
mapStructBeanCopy 编译期生成get、set 基于MapStruct进行属性转换

Benchmark性能测试源码

Benchmark性能测试对比

  • 循环1000次性能数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Benchmark                         (loop)   Mode  Cnt       Score       Error  Units
    BeanCopyTest.apacheBeanCopy 1000 thrpt 5 5.444 ± 1.016 ops/s
    BeanCopyTest.beanAsmBeanCopy 1000 thrpt 5 3207.672 ± 275.027 ops/s
    BeanCopyTest.beanCopierBeanCopy 1000 thrpt 5 81902.789 ± 25799.131 ops/s
    BeanCopyTest.beanMappingBeanCopy 1000 thrpt 5 1071.160 ± 40.030 ops/s
    BeanCopyTest.dozerBeanCopy 1000 thrpt 5 2.715 ± 1.438 ops/s
    BeanCopyTest.fastJsonBeanCopy 1000 thrpt 5 913.955 ± 93.294 ops/s
    BeanCopyTest.getSetBeanCopy 1000 thrpt 5 108190.483 ± 11367.291 ops/s
    BeanCopyTest.mapStructBeanCopy 1000 thrpt 5 98433.589 ± 9000.043 ops/s
    BeanCopyTest.modelMapperBeanCopy 1000 thrpt 5 341.047 ± 213.611 ops/s
    BeanCopyTest.orikaBeanCopy 1000 thrpt 5 2123.308 ± 413.037 ops/s
    BeanCopyTest.springBeanCopy 1000 thrpt 5 404.477 ± 210.129 ops/s
  • 循环10000次性能数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Benchmark                         (loop)   Mode  Cnt      Score     Error  Units
    BeanCopyTest.apacheBeanCopy 10000 thrpt 5 0.634 ± 0.075 ops/s
    BeanCopyTest.beanAsmBeanCopy 10000 thrpt 5 341.249 ± 46.345 ops/s
    BeanCopyTest.beanCopierBeanCopy 10000 thrpt 5 10140.338 ± 974.494 ops/s
    BeanCopyTest.beanMappingBeanCopy 10000 thrpt 5 101.530 ± 48.186 ops/s
    BeanCopyTest.dozerBeanCopy 10000 thrpt 5 0.335 ± 0.021 ops/s
    BeanCopyTest.fastJsonBeanCopy 10000 thrpt 5 112.156 ± 11.229 ops/s
    BeanCopyTest.getSetBeanCopy 10000 thrpt 5 11149.563 ± 831.699 ops/s
    BeanCopyTest.mapStructBeanCopy 10000 thrpt 5 10504.837 ± 645.696 ops/s
    BeanCopyTest.modelMapperBeanCopy 10000 thrpt 5 46.042 ± 1.786 ops/s
    BeanCopyTest.orikaBeanCopy 10000 thrpt 5 218.724 ± 15.450 ops/s
    BeanCopyTest.springBeanCopy 10000 thrpt 5 51.478 ± 6.783 ops/s
  • 循环100000次性能数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Benchmark                         (loop)   Mode  Cnt    Score     Error  Units
    BeanCopyTest.apacheBeanCopy 100000 thrpt 5 0.071 ± 0.006 ops/s
    BeanCopyTest.beanAsmBeanCopy 100000 thrpt 5 32.620 ± 3.874 ops/s
    BeanCopyTest.beanCopierBeanCopy 100000 thrpt 5 646.601 ± 76.820 ops/s
    BeanCopyTest.beanMappingBeanCopy 100000 thrpt 5 10.471 ± 2.635 ops/s
    BeanCopyTest.dozerBeanCopy 100000 thrpt 5 0.029 ± 0.003 ops/s
    BeanCopyTest.fastJsonBeanCopy 100000 thrpt 5 9.685 ± 1.250 ops/s
    BeanCopyTest.getSetBeanCopy 100000 thrpt 5 571.465 ± 153.503 ops/s
    BeanCopyTest.mapStructBeanCopy 100000 thrpt 5 441.470 ± 306.007 ops/s
    BeanCopyTest.modelMapperBeanCopy 100000 thrpt 5 4.380 ± 0.950 ops/s
    BeanCopyTest.orikaBeanCopy 100000 thrpt 5 18.668 ± 1.685 ops/s
    BeanCopyTest.springBeanCopy 100000 thrpt 5 4.765 ± 2.302 ops/s

总结

  • 对象属性转换的操作无非是基于反射、AOP、CGlib、ASM、Javassist在编译时和运行期进行处理,再有好的思路就是在编译前生成出对应的get、set,就像手写出来的一样。
  • property少,写起来也不麻烦,就直接用传统的getter/setter,性能最好。
  • property多,转换很频繁,建议直接用MapStruct,编译时生成get、set方法,性能最优。
  • 如果不习惯用MapStruct,其次建议用BeanCopier,性能跟MapStruct接近,但是BeanCopier的创建时消耗较大,所以不要频繁创建该实体,最好的处理方式是静态化或者缓存起来。

If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !

...

...

00:00
00:00