反射+Set测试
使用的类:org.springframework.beans.BeanUtils.copyProperties(source, target)
代码
@Test
public void test() {
PriceAdjustBean adjustBean = new PriceAdjustBean();
adjustBean.setSkuId(111111);
adjustBean.setOrderId("ST2019070112064948900018");
adjustBean.setAdjustedPrice(100000L);
adjustBean.setAdjustedType(1);
long now = System.currentTimeMillis();
int count = 10000;
System.out.println("循环次数:" + count);
for (int i = 0; i < count; i++) {
OrderPriceAdjustment orderPriceAdjustment = new OrderPriceAdjustment();
BeanUtils.copyProperties(adjustBean, orderPriceAdjustment);
}
long after = System.currentTimeMillis();
System.out.println("反射耗时:" + (after - now));
for (int i = 0; i < count; i++) {
OrderPriceAdjustment orderPriceAdjustment = new OrderPriceAdjustment();
orderPriceAdjustment.setOrderId(adjustBean.getOrderId());
orderPriceAdjustment.setSkuId(adjustBean.getSkuId());
orderPriceAdjustment.setAdjustedType(adjustBean.getAdjustedType());
orderPriceAdjustment.setAdjustedPrice(adjustBean.getAdjustedPrice());
}
long result = System.currentTimeMillis();
System.out.println("set 耗时:" + (result - after));
}
结果
循环次数 | 反射耗时(ms) | Set耗时(ms) |
---|---|---|
1 | 491 | 0 |
10 | 506 | 0 |
100 | 487 | 1 |
1000 | 458 | 0 |
2000 | 493 | 0 |
4000 | 573 | 2 |
8000 | 541 | 3 |
10000 | 553 | 6 |
100000 | 916 | 19 |
1000000 | 1993 | 22 |
当前数据只是一次执行的结果,该方法底层做了一些其他的特殊处理,使得服务启动之后,一个类的属性拷贝,时间基本能维持的相对比较低。详情参见CachedIntrospectionResults
类。
结论
Set方法的耗时明显少于反射处理的耗时。
在上述数据集的结果中可以看出,这种反射的处理,耗时还是非常明显的,即使在数据量很少的情况下,这种处理方式代码无疑显得很整齐简洁,但是效率太低,不提倡
。另外,BeanUtils的拷贝,写的简洁,导致其实在执行完之后,我们不能很明显的知道究竟多少属性被拷贝了。
不可一味的为了追求代码的简洁,忽略了性能的问题。往往比较严重的性能问题都是由这种小问题堆积而来的,防微杜渐。
当然事无绝对
,存在必然有一定的意义。在一些框架性的结构中的通用代码,还是会无可避免的使用到这种方式。