为什么RandomAccessFile writeLong用多次写调用实现?

jas*_*cao 5 java io performance

在分析应用程序时,我注意到RandomAccessFile.writeLong花了很多时间.

我检查了这个方法的代码,它涉及8次本机方法写入调用.我使用byte []为writeLong编写了一个替代实现.像这样的东西:

RandomAccessFile randomAccessFile = new RandomAccessFile("out.dat", "rwd");
...
byte[] aux = new byte[8];
aux[0] = (byte) ((l >>> 56) & 0xFF);
aux[1] = (byte) ((l >>> 48) & 0xFF);
aux[2] = (byte) ((l >>> 40) & 0xFF);
aux[3] = (byte) ((l >>> 32) & 0xFF);
aux[4] = (byte) ((l >>> 24) & 0xFF);
aux[5] = (byte) ((l >>> 16) & 0xFF);
aux[6] = (byte) ((l >>> 8) & 0xFF);
aux[7] = (byte) ((l >>> 0) & 0xFF);
randomAccessFile.write(aux);
Run Code Online (Sandbox Code Playgroud)

我做了一个小基准测试并得到了这些结果:

使用writeLong():
调用的平均时间:91 ms

使用write(byte []):
调用的平均时间:11 ms

在具有Intel(R)CPU T2300 @ 1.66GHz的Linux机器上进行测试

由于本机调用会有一些性能损失,为什么writeLong会以这种方式实现?我知道应该向太阳队员提出这个问题,但我希望这里的人有一些提示.

谢谢.

Ano*_*non 2

我会投票支持懒惰,或者(更仁慈地)不考虑后果。

的本机实现writeLong()可能需要每个体系结构的版本来处理字节顺序(JNI 将转换为平台字节顺序)。通过将翻译保留在“跨平台”层,开发人员简化了移植工作。

至于为什么它们在 Java 端没有转换为数组,我怀疑这是由于担心垃圾收集。我猜想RandomAccessFile自 1.1 以来这已经发生了微小的变化,直到 1.3 垃圾收集才开始使小对象分配变得“免费”。

但是,还有一个替代方案RandomAccessFile:看看MappedByteBuffer


编辑:我有一台装有 JDK 1.2.2 的机器,此方法从那时起就没有改变。