Java 深度拷贝测试

测试选择了两种深度拷贝的方式

  • Object Stream
  • fast-serialization

fast-serialization 是一个开源的高性能的序列化库。

RuedigerMoeller/fast-serialization

使用 idea 新建一个 maven 项目,引入需要的开源工具 JMH 和上面的 fast-serialization。

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-core</artifactId>
      <version>1.25.2</version>
    </dependency>

    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-generator-annprocess</artifactId>
      <version>1.25.2</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>de.ruedigermoeller</groupId>
      <artifactId>fst</artifactId>
      <version>2.57</version>
    </dependency>
<dependencies>

使用 Object Stream 和 fast-serialization 写出两个深度拷贝的方法

public class DeepCopyUtils {

    private static FSTConfiguration configuration = FSTConfiguration.createDefaultConfiguration();

    public static <T> T fstDeepCopy(T src) {
        return configuration.deepCopy(src);
    }

    public static <T> T deepCopy(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);

            return (T)in.readObject();
        } catch ( Exception e) {

        }
        return null;
    }

}

使用 JMH 写一个基准测试类

@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 10)
@Measurement(iterations = 50, time = 3, timeUnit = TimeUnit.SECONDS)
@Threads(8)
@Fork(2)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class DeepCopyBenchmark {

    private static UserData userData = new UserData();

    static {
        userData.setBetCoins(1000000L);

        List<String> modes = new ArrayList<>();
        modes.add("DEEP");
        modes.add("COPY");
        userData.setModes(modes);

        List<Object> storedIcons = new ArrayList<>();

        List<Object> icon1 = new ArrayList<>();
        icon1.add(1);
        icon1.add(new BigDecimal(100));
        storedIcons.add(icon1);
        userData.setStoredIcon(storedIcons);

        userData.setOhter(new Othre());
        userData.setUid(1L);
    }

    @Benchmark
    public void testFstDeepCopy() {
        DeepCopyUtils.fstDeepCopy(userData);
    }

    @Benchmark
    public void testDeepCopy() {
        DeepCopyUtils.deepCopy(userData);
    }
    
}

编写一个运行基准测试方法

public static void main( String[] args ) throws RunnerException {
        Options options = new OptionsBuilder()
            .include(DeepCopyBenchmark.class.getSimpleName())
            .output("/Users/admin/deep_copy_benchmark.log")
            .build();
        new Runner(options).run();
    }

打开输出日志 deep_copy_benchmark.log

Benchmark                           Mode  Cnt     Score    Error   Units
DeepCopyBenchmark.testDeepCopy     thrpt  100    82.756 ±  2.047  ops/ms
DeepCopyBenchmark.testFstDeepCopy  thrpt  100  1177.081 ± 11.151  ops/ms

很明显 fast-serialization 强得不是一点半点。


Simeone_xu
1.3k 声望14 粉丝

一个爱看球的程序员