Abi*_*idi 5 java bytebuffer jmh
我想比较直接字节缓冲区(java.nio.ByteBuffer,堆外)和堆缓冲区(通过数组实现)的读取和写入性能。我的理解是,ByteBuffer 在堆外比堆缓冲区至少有两个好处。首先,它不会被 GC 考虑,其次(我希望我做对了)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]);
});
}
}
Run Code Online (Sandbox Code Playgroud)
运行完成。总时间:00:00:37
基准 (N) 模式 Cnt 分数误差单位
BasicTest.heapBuffer 100000 avgt 10 0.039 ± 0.003 ms/op
BasicTest.offHeapBuffer 100000 avgt 10 0.050 ± 0.007 ms/op
不会被 GC 考虑
当然GC会考虑。
垃圾收集器确定缓冲区不再使用,然后释放内存。
我不应该期望我的基准测试显示 [该] 堆外缓冲区 [is] 比堆缓冲区快吗?
堆外不会使缓冲区更快地进行内存访问。
一个直接缓冲区会更快,当Java的交流与操作系统的缓冲区的字节数。由于您的代码不执行 I/O,因此使用直接缓冲区没有性能优势。
正如javadoc所说:
给定一个直接字节缓冲区,Java 虚拟机将尽最大努力直接在其上执行本机 I/O 操作。也就是说,它将尝试避免在每次调用底层操作系统的本机 I/O 操作之前(或之后)将缓冲区的内容复制到(或从)中间缓冲区。
| 归档时间: |
|
| 查看次数: |
2882 次 |
| 最近记录: |