测试以下两种拷贝方式:
- 使用spring的BeanUtils(反射调用getset)
- gson序列化
简单封装的工具类:
public class BeanUtil {
private static Gson gson = GsonUtil.getInstance();
private BeanUtil() {
throw new IllegalStateException("Utility class");
}
public static <T, S> T convertBeanSpring(S source, Class<T> targetType) throws IllegalAccessException, InstantiationException {
if (source == null) {
throw new NullPointerException("Source bean cannot be null");
}
T target = targetType.newInstance();
BeanUtils.copyProperties(source, target);
return target;
}
public static <T, S> T convertBeanGson(S source, Class<T> targetType) {
if (source == null) {
throw new NullPointerException("Source bean cannot be null");
}
return gson.fromJson(gson.toJson(source), targetType);
}
}
测试方法
@Test
public void beanUtilPerformanceTest() {
long beforeTime = System.currentTimeMillis();
int range = 5000000;
Class1 class1 = new Class1();
IntStream.range(0, range).forEach(i -> {
try {
BeanUtil.convertBeanGson(class1, Class2.class);
} catch (Exception e) {
}
});
System.out.println(String.format("Loop %d times, gson copy spend time %d ms", range, (System.currentTimeMillis() - beforeTime)));
beforeTime = System.currentTimeMillis();
IntStream.range(0, range).forEach(i -> {
try {
BeanUtil.convertBeanSpring(class1, Class2.class);
} catch (Exception e) {
}
});
System.out.println(String.format("Loop %d times, spring copy spend time %d ms", range, (System.currentTimeMillis() - beforeTime)));
}
测试结果:
Loop 5000000 times, gson copy spend time 9188 ms
Loop 5000000 times, spring copy spend time 14381 ms
调换顺序再测一次(jvm的预热机制)
Loop 5000000 times, spring copy spend time 15279 ms
Loop 5000000 times, gson copy spend time 7883 ms
预热对代码执行速度还是有影响的,但这个数据也足以看出gson序列化拷贝的速度优于反射拷贝。
但是序列化拷贝也有缺点,因为这是弱类型拷贝,会出现类型不一致的同名字段被覆盖的情况,getset则不会,看情况使用吧。