基於JMH對Java NIO 零拷貝進行基準測試

背景

Java NIO中引入了零拷貝的API,本文測試零拷貝與傳統IO的性能差異,通過藉助基準測試工具JMH進行測試

測試用例

簡單些了一個JMH的實例,迭代100次,計算每次的平均時間

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

/**
 * 通過複製文件來測試 傳統IO VS 零拷貝 的性能
 */
@Warmup(iterations = 1) // 預熱迭代次數
@Measurement(iterations = 100)  // 測試迭代測試,作爲計算的依據
@Fork(1) // 模擬1個線程處理
@BenchmarkMode(Mode.SingleShotTime) // 每次迭代執行一次的時間
public class ZeroCopyTest {

    /**
     * 基準測試用例,測試零拷貝性能
     * @throws IOException
     */
    @Benchmark
    public void testWithZeroCopy() throws IOException {
        FileInputStream inputStream = new FileInputStream("D:\\soft\\YNote.exe");
        File outFile = new File("pdi.zip");
        FileOutputStream outputStream = new FileOutputStream(outFile, false);
        FileChannel inputChannel = inputStream.getChannel();
        FileChannel outChannel = outputStream.getChannel();
        outChannel.position(0);
        inputChannel.transferTo(0, inputChannel.size(), outChannel);
        inputStream.close();
        outputStream.close();
    }

    /**
     * 基準測試用例,測試傳統IO性能
     * @throws IOException
     */
    @Benchmark
    public void testWithoutZeroCopy() throws IOException {
        FileInputStream inputStream = new FileInputStream("D:\\soft\\YNote.exe");
        File outFile = new File("pdi.zip");
        FileOutputStream outputStream = new FileOutputStream(outFile, false);
        byte[] buffer = new byte[4086];
        while (true) {
            int length = inputStream.read(buffer);
            if (length < 0) {
                break;
            }
            outputStream.write(buffer, 0, length);
        }
        outputStream.flush();
        inputStream.close();
        outputStream.close();
    }

    /**
     * 通過main方法的方式啓動JMH測試,也可以通過命令啓動,具體方法可使用搜索引擎查詢
     * @param args
     * @throws RunnerException
     * @throws IOException
     */
    public static void main(String[] args) throws RunnerException, IOException {
        Options opt = new OptionsBuilder()
                .include(ZeroCopyTest.class.getSimpleName())
                .build();
        new Runner(opt).run();
    }

}

結果分析

由於每個用例執行了100次,具體的每次的執行時間就不做輸出,下面是統計結果部分

Benchmark                         Mode  Cnt  Score           Error  Units
ZeroCopyTest.testWithZeroCopy       ss  100  0.051 ± 0.004          s/op
ZeroCopyTest.testWithoutZeroCopy    ss  100  0.170 ± 0.006          s/op

從統計結果看,使用零拷貝的效率,大概是傳統IO的3倍多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章