JavaWeb - 深度拷贝方式和性能对比(三)

简介: JavaWeb - 深度拷贝方式和性能对比(三)

四、性能对比

创建一个50个字段的对象,并使用不同的深度拷贝方式,创建对象N多遍。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeepCopyEntity implements Cloneable, Serializable {
    /**
     * 序列化标识
     */
    private static final long serialVersionUID = 6172279441386879379L;
    @Override
    protected DeepCopyEntity clone() {
        try {
            return (DeepCopyEntity)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
    private String id;
    private String field1;
    private String field2;
    private String field3;
    private String field4;
    private String field5;
    private String field6;
    private String field7;
    private String field8;
    private String field9;
    private String field10;
    private String field11;
    private String field12;
    private String field13;
    private String field14;
    private String field15;
    private String field16;
    private String field17;
    private String field18;
    private String field19;
    private String field20;
    private String field21;
    private String field22;
    private String field23;
    private String field24;
    private String field25;
    private String field26;
    private String field27;
    private String field28;
    private String field29;
    private String field30;
    private String field31;
    private String field32;
    private String field33;
    private String field34;
    private String field35;
    private String field36;
    private String field37;
    private String field38;
    private String field39;
    private String field40;
    private String field41;
    private String field42;
    private String field43;
    private String field44;
    private String field45;
    private String field46;
    private String field47;
    private String field48;
    private String field49;
    private String field50;
}
package com.kevin.deepcopy;
import com.esotericsoftware.kryo.Kryo;
import net.sf.json.JSONObject;
import org.springframework.util.StopWatch;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
 *  深度拷贝类型        循环次数[1000]      循环次数[10000]      循环次数[1000000]
 *  new               5 ms               14 ms              133 ms
 *
 *  Cloneable:        < 1 ms             7 ms               88 ms
 *
 *  Jdk序列化:         272 ms             1589 ms            66190 ms
 *
 *  Kryo序列化:        95 ms              123 ms             2438 ms
 *
 *  Json序列化:        1203 ms            3746 ms            163512 ms
 *
 *  总结: 1)、序列化性能   Clone > new > Kryo序列化 > Jdk序列化 > Json(各种Json类似)序列化
 *        2)、Clone深拷贝性能最高,但是如果属性中有特定的对象字段,则需要自己编写代码
 *        3)、new 性能仅次于Clone,因为需要执行Jvm过程(常量池判断,内存分配,值初始化,init方法调用,栈中对象的引用等),并且主要是每个对象需要单独编写代码,当然也不建议使用反射
 *        4)、kryo 性能较高,并且不需要单独的开发,  若对性能不是特别高,可以考虑使用.(kryo是非线程安全的,项目中使用时可以放入ThreadLocal中)
 *        5)、Jdk序列化和Json序列化,性能太低,高性能项目不建议使用
 *
 *  总结的总结: 如果性能要求特别高(或者对象结构层次不深),可以使用Clone方式;否则可以考虑使用 Kryo序列化和反序列化实现对象深拷贝
 *
 * @author kevin
 * @date 2020/9/27 13:45
 * @since 1.0.0
 */
public class DeepCopyTest {
    /**
     * 循环的次数
     */
    private static final int LOOP = 1000;
    private static Kryo kryo = new Kryo();
    public static void main(String[] args) throws Exception {
        DeepCopyEntity demo = getInit();
        StopWatch stopWatch = new StopWatch("测试深拷贝");
        stopWatch.start();
        for (int i = 0; i < LOOP; i++) {
//            DeepCopyEntity deep = newObject(demo);
            final DeepCopyEntity deep = demo.clone();
//            final DeepCopyEntity deepCopyEntity = copyImplSerializable(demo);
//            final DeepCopyEntity deepCopyEntity = copyByKryo(demo);
//            final DeepCopyEntity deepCopyEntity1 = copyByJson(demo);
        }
        stopWatch.stop();
        System.out.println(stopWatch.prettyPrint());
    }
    /**
     * 深层拷贝 - 需要net.sf.json.JSONObject
     * @param <T>
     * @param obj
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public static <T> T copyByJson(T obj) throws Exception {
        return (T) JSONObject.toBean(JSONObject.fromObject(obj),obj.getClass());
    }
    /**
     *
     * @param source
     * @return
     */
    public static DeepCopyEntity copyByKryo(DeepCopyEntity source){
        return kryo.copy(source);
    }
    /**
     * 深层拷贝 - 需要类继承序列化接口
     * @param <T>
     * @param obj
     * @return
     * @throws Exception
     * @see java.io.Closeable
     * @see AutoCloseable 不用进行关闭
     */
    @SuppressWarnings("unchecked")
    public static <T> T copyImplSerializable(T obj) throws Exception {
        ByteArrayOutputStream baos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        Object o = null;
        //如果子类没有继承该接口,这一步会报错
        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            bais = new ByteArrayInputStream(baos.toByteArray());
            ois = new ObjectInputStream(bais);
            o = ois.readObject();
            return (T) o;
        } catch (Exception e) {
            throw new Exception("对象中包含没有继承序列化的对象");
        }
    }
    private static DeepCopyEntity newObject(DeepCopyEntity demo) {
        final DeepCopyEntity deepCopyEntity = new DeepCopyEntity();
        deepCopyEntity.setId(demo.getId());
        deepCopyEntity.setField1(demo.getField1());
        deepCopyEntity.setField2(demo.getField2());
        deepCopyEntity.setField3(demo.getField1());
        deepCopyEntity.setField4(demo.getField1());
        deepCopyEntity.setField5(demo.getField1());
        deepCopyEntity.setField6(demo.getField1());
        deepCopyEntity.setField7(demo.getField1());
        deepCopyEntity.setField8(demo.getField1());
        deepCopyEntity.setField9(demo.getField1());
        deepCopyEntity.setField10(demo.getField1());
        deepCopyEntity.setField11(demo.getField1());
        deepCopyEntity.setField12(demo.getField1());
        deepCopyEntity.setField13(demo.getField1());
        deepCopyEntity.setField14(demo.getField1());
        deepCopyEntity.setField15(demo.getField1());
        deepCopyEntity.setField16(demo.getField1());
        deepCopyEntity.setField17(demo.getField1());
        deepCopyEntity.setField18(demo.getField1());
        deepCopyEntity.setField19(demo.getField1());
        deepCopyEntity.setField20(demo.getField1());
        deepCopyEntity.setField21(demo.getField1());
        deepCopyEntity.setField22(demo.getField1());
        deepCopyEntity.setField23(demo.getField1());
        deepCopyEntity.setField24(demo.getField1());
        deepCopyEntity.setField25(demo.getField1());
        deepCopyEntity.setField26(demo.getField1());
        deepCopyEntity.setField27(demo.getField1());
        deepCopyEntity.setField28(demo.getField1());
        deepCopyEntity.setField29(demo.getField1());
        deepCopyEntity.setField30(demo.getField1());
        deepCopyEntity.setField31(demo.getField1());
        deepCopyEntity.setField32(demo.getField1());
        deepCopyEntity.setField33(demo.getField1());
        deepCopyEntity.setField34(demo.getField1());
        deepCopyEntity.setField35(demo.getField1());
        deepCopyEntity.setField36(demo.getField1());
        deepCopyEntity.setField37(demo.getField1());
        deepCopyEntity.setField38(demo.getField1());
        deepCopyEntity.setField39(demo.getField1());
        deepCopyEntity.setField40(demo.getField1());
        deepCopyEntity.setField41(demo.getField1());
        deepCopyEntity.setField42(demo.getField1());
        deepCopyEntity.setField43(demo.getField1());
        deepCopyEntity.setField44(demo.getField1());
        deepCopyEntity.setField45(demo.getField1());
        deepCopyEntity.setField46(demo.getField1());
        deepCopyEntity.setField47(demo.getField1());
        deepCopyEntity.setField48(demo.getField1());
        deepCopyEntity.setField49(demo.getField1());
        deepCopyEntity.setField50(demo.getField1());
        return deepCopyEntity;
    }
    /**
     * 获取初始化值
     * @return demo对象
     */
    private static DeepCopyEntity getInit() {
        final DeepCopyEntity deepCopyEntity = new DeepCopyEntity();
        deepCopyEntity.setId("测试字段进来撒个是个是个复活节快乐时刻六公里按时交付格拉斯可根据ask了接受了嘎嘎健康金克拉是个零售价格克拉斯关键时刻两个jklsghbld时间噶设立国家级法国设计规划拉萨尽快赶回监考老师的风格就是看来撒骨灰两个据类");
        // 省略后面所有字段的设置,都设置一样的字段 ......
        return deepCopyEntity;
    }
}

总结

1)、序列化性能 Clone > new > Kryo序列化 > Jdk序列化 > Json(各种Json类似)序列化

2)、Clone深拷贝性能最高,但是如果属性中有特定的对象字段,则需要自己编写代码

3)、new 性能仅次于Clone,因为需要执行Jvm过程(常量池判断,内存分配,值初始化,init方法调用,栈中对象的引用等),并且主要是每个对象需要单独编写代码,当然也不建议使用反射

4)、kryo 性能较高,并且不需要单独的开发, 若对性能不是特别高,可以考虑使用。kryo是非线程安全的,项目中使用时可以放入ThreadLocal中

5)、Jdk序列化和Json序列化,性能太低,高性能项目不建议使用

如果性能要求特别高(或者对象结构层次不深),可以使用Clone方式;否则可以考虑使用 Kryo序列化和反序列化实现对象深拷贝!

目录
相关文章
|
24天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第3天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin的兴起,其在Android开发中的地位逐渐上升,但关于其与Java在性能方面的对比,尚无明确共识。本文通过深入分析并结合实际测试数据,探讨了Kotlin与Java在Android平台上的性能表现,揭示了在不同场景下两者的差异及其对应用性能的潜在影响,为开发者在选择编程语言时提供参考依据。
|
1月前
|
Web App开发 SQL Java
javaweb实现分页(二)
javaweb实现分页(二)
19 1
|
1月前
|
SQL 关系型数据库 MySQL
javaweb实现分页查询(一)
javaweb实现分页查询(一)
19 0
|
1月前
|
SQL 关系型数据库 MySQL
javaweb中实现分页,持续更新……
javaweb中实现分页,持续更新……
17 1
|
1月前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第30天】 随着Kotlin成为开发Android应用的首选语言,开发者社区对于其性能表现持续关注。本文通过深入分析与基准测试,探讨Kotlin与Java在Android平台上的性能差异,揭示两种语言在编译效率、运行时性能和内存消耗方面的具体表现,并提供优化建议。我们的目标是为Android开发者提供科学依据,帮助他们在项目实践中做出明智的编程语言选择。
|
1月前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
在开发高性能的Android应用时,选择合适的编程语言至关重要。近年来,Kotlin因其简洁性和功能性受到开发者的青睐,但其性能是否与传统的Java相比有所不足?本文通过对比分析Kotlin与Java在Android平台上的运行效率,揭示二者在编译速度、运行时性能及资源消耗方面的具体差异,并探讨在实际项目中如何做出最佳选择。
18 4
|
11天前
|
SQL 缓存 Java
Java数据库连接池:优化数据库访问性能
【4月更文挑战第16天】本文探讨了Java数据库连接池的重要性和优势,它能减少延迟、提高效率并增强系统的可伸缩性和稳定性。通过选择如Apache DBCP、C3P0或HikariCP等连接池技术,并进行正确配置和集成,开发者可以优化数据库访问性能。此外,批处理、缓存、索引优化和SQL调整也是提升性能的有效手段。掌握数据库连接池的使用是优化Java企业级应用的关键。
|
15天前
|
存储 Java 测试技术
Java 21革命性升级:探索分代ZGC的性能奇迹
Java 21革命性升级:探索分代ZGC的性能奇迹
14 0
|
26天前
|
缓存 算法 Java
Java内存管理:优化性能和避免内存泄漏的关键技巧
综上所述,通过合适的数据结构选择、资源释放、对象复用、引用管理等技巧,可以优化Java程序的性能并避免内存泄漏问题。
27 5
|
1月前
|
SQL 前端开发 Java
Java后端进阶之路: JavaWeb(四)
Java后端进阶之路: JavaWeb
33 1