我想比较直接字节缓冲区(java.nio.ByteBuffer,非堆)和堆缓冲区(通过数组实现)在读写方面的性能。我的理解是,ByteBuffer 是非堆的,因此至少有两个优点。首先,它不会被视为垃圾回收的对象;其次(我希望我理解得正确),JVM 在从中读取和写入时不会使用中间/临时缓冲区。这些优点可能使非堆缓冲区比堆缓冲区更快。如果是这样的话,我难道不应该期望我的基准测试结果也是一样的吗?但事实上,它总是显示堆缓冲区比非堆缓冲区更快。
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 2, jvmArgs = {"-Xms2G", "-Xmx4G"})
@Warmup(iterations = 3)
@Measurement(iterations = 10)
public class BasicTest {
@Param({"100000"})
private int N;
final int bufferSize = 10000;
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8 * bufferSize);
long buffer[] = new long[bufferSize];
public static void main(String arep[]) throws Exception {
Options opt = new OptionsBuilder()
.include(BasicTest.class.getSimpleName())
.forks(1)
.build();
new Runner(opt).run();
}
@Benchmark
public void offHeapBuffer(Blackhole blackhole) {
IntStream.range(0, bufferSize).forEach(index -> {
byteBuffer.putLong(index, 500 * index);
blackhole.consume(byteBuffer.get(index));
});
}
@Benchmark
public void heapBuffer(Blackhole blackhole) {
IntStream.range(0, bufferSize).forEach(index -> {
buffer[index] = 500 * index;
blackhole.consume(buffer[index]);
});
}
}
执行完成。总时间:00:00:37
基准测试 (N) 模式 数量 得分 误差 单位
BasicTest.heapBuffer 100000 平均 10 0.039 ± 0.003 毫秒/操作
BasicTest.offHeapBuffer 100000 平均 10 0.050 ± 0.007 毫秒/操作