背景
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倍多。