几种copyProperties工具类性能比较

时间:2024-04-09 11:26:03

最近的项目有用到
PropertyUtils.copyProperties(info, daoInfo);
便来总结一下。
阿里发布了阿里巴巴代码规约插件,果断将它集成起来。我最喜欢使用的Apache BeanUtils.copyProperties()方法后面打了个大大的红叉,提示"避免使用Apache的BeanUtils进行属性的copy"。

市面上的其他几种属性copy工具

  1. springframework的BeanUtils
  2. cglib的BeanCopier
  3. Apache BeanUtils包的PropertyUtils类

测试一下
几种copyProperties工具类性能比较

结论:

  1. PropertyUtils的copyProperties()方法几乎与BeanUtils.copyProperties()相同,主要的区别在于后者提供类型转换功能,
    即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,PropertyUtils不支持这个功能,所以说BeanUtils速度会更快一些,
    使用更普遍一点,犯错的风险更低一点。

  2. Apache BeanUtils的性能最差,不建议使用。

  3. Apache PropertyUtils100000次以内性能还能接受,到百万级别性能就比较差了,可酌情考虑。

  4. spring BeanUtils和BeanCopier性能较好,如果对性能有特别要求,可使用BeanCopier,不然spring BeanUtils也是可取的。

Apache BeanUtils.copyProperties()性能分析

执行1000000次copy属性,然后通过jvisualvm查看方法耗时,如图:

发现最耗时的方法就是method.invoke(),但是spring的BeanUtils、PropertyUtils里也是采用反射来实现的,为什么效率相差这么大呢?

看来Abstract.convert()和getIntrospectionData()占用了很大一部分时间,
而且Apache BeanUtils中的日志输出也比较耗时。

Spring BeanUtils和PropertyUtils

几种copyProperties工具类性能比较
PropertyUtils和Apache BeanUtils核心代码区别在图中标注的地方。Apache BeanUtils主要集中了各种丰富的功能(日志、转换、解析等等),导致性能变差。

而Spring BeanUtils则是直接通过反射来读取和写入,直抒胸臆,省去了其他繁杂的步骤,性能自然不差。

Cglib BeanCopier

cglib BeanCopier的主要耗时方法就在BeanCopier.create(),如果将该方法做成静态成员变量,则还可以大大缩小执行时间。BeanCopier是一种基于字节码的方式,其实就是通过字节码方式转换成性能最好的get、set方式,只需考虑创建BeanCopier的开销,如果我们将BeanCopier做成静态的,基本只需考虑get、set的开销,所以性能接近于get、set。