天天看點

深拷貝最佳實踐

作者:NEDHOME

深拷貝(clone)是 Java 開發過程中經常遇到問題,有人用 IO 流、有人用 JSON 序列化、有人循環拷貝屬性等等,網上文章都能實作功能。

問題:

clone 屬于計算操作,消耗 CPU 如果速度慢(高并發場景幾十毫秒也是非常慢的)會導緻程式卡頓,QPS 降低。網上解決方案都沒有提到性能問題,我實際使用後對性能進行了優化,最後推薦 FastClone。

FastClone 介紹

FastClone 是一款非常好用,支援大部分場景深克隆和淺克隆的工具。被推薦的不多,被埋沒了。

<dependency>
  <groupId>com.github.bruce-cloud</groupId>
  <artifactId>fastclone</artifactId>
  <version>1.0.RELEASE</version>
</dependency>           

用法:

// 深克隆list
FastClone fastClone = new FastClone();
List<T> clone = fastClone.clone(src);


// 深克隆list
FastClone fastClone = new FastClone();
List<T> clone = fastClone.cloneShallow(src);           

性能對比

我們項目中用了三種方式對大對象進行深克隆對比 clone:

1. 使用 IO 流寫入再讀取出來,平均耗時 52ms,也就是會占用 52ms 的 CPU。

public static <T> List <T> deepCopy(List <T> src) {
    try {
        ByteArrayOutputStream byteout = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteout);
        out.writeObject(src);
        ByteArrayInputStream bytein = new ByteArrayInputStream(byteout.toByteArray());
        ObjectInputStream in = new ObjectInputStream(bytein);
        @SuppressWarnings("unchecked")
        List < T > dest = (List < T > ) in .readObject();
        return dest;
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return null;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}           
深拷貝最佳實踐

2. 使用阿裡巴巴 fastjson 反序列化先轉 JSON 再轉對象,平均耗時 65ms,也就是會占用 65ms 的 CPU。

String jsonString = JSON.toJSONString(arrayList);
List < Symbol > configCoinSymbols = JSON.parseArray(jsonString, Symbol.class);           
深拷貝最佳實踐

3. 使用 FastClone 反序列化平均耗時 3.4ms,也就是會占用 3.4ms 的 CPU。比其他方式快了将近 20 倍。不過 FastClone 有個缺點,就是不支援 ConcurrentHashMap,其他主流集合都支援。

深拷貝最佳實踐
深拷貝最佳實踐

結論

複雜對象使用其他方式深克隆,會導緻 CPU 飙升,QPS下降,接口響應逾時等情況。FastClone 性能方面非常好。blog.csdn.net/zjy_love_java/article/details/119465427