gpt4 book ai didi

java - 为什么 RandomAccessFile writeLong 是通过多次写入调用实现的?

转载 作者:搜寻专家 更新时间:2023-10-31 20:15:39 29 4
gpt4 key购买 nike

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

我查了下这个方法的代码,涉及8次native方法write的调用。我使用 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);

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

Using writeLong():
Average time for invocation: 91 ms

Using write(byte[]):
Average time for invocation: 11 ms

在配备 Intel(R) CPU T2300 @ 1.66GHz 的 Linux 机器上测试运行

既然本地调用有一些性能损失,为什么 writeLong 以这种方式实现?我知道应该向 Sun 的人提出这个问题,但我希望这里有人能提供一些提示。

谢谢。

最佳答案

看来 RandomAccessFile.writeLong() 并没有最小化对操作系统的调用次数。使用“rwd”而不是“rw”会显着增加成本,这应该足以表明它不是花费时间的调用本身。 (事实上​​,操作系统试图将每次写入提交到磁盘,而磁盘的旋转速度如此之快)

{
RandomAccessFile raf = new RandomAccessFile("test.dat", "rwd");
int longCount = 10000;
long start = System.nanoTime();
for (long l = 0; l < longCount; l++)
raf.writeLong(l);
long time = System.nanoTime() - start;
System.out.printf("writeLong() took %,d us on average%n", time / longCount / 1000);
raf.close();
}
{
RandomAccessFile raf = new RandomAccessFile("test2.dat", "rwd");
int longCount = 10000;
long start = System.nanoTime();
byte[] aux = new byte[8];
for (long l = 0; l < longCount; l++) {
aux[0] = (byte) (l >>> 56);
aux[1] = (byte) (l >>> 48);
aux[2] = (byte) (l >>> 40);
aux[3] = (byte) (l >>> 32);
aux[4] = (byte) (l >>> 24);
aux[5] = (byte) (l >>> 16);
aux[6] = (byte) (l >>> 8);
aux[7] = (byte) l;
raf.write(aux);
}
long time = System.nanoTime() - start;
System.out.printf("write byte[8] took %,d us on average%n", time / longCount / 1000);
raf.close();
}

打印

writeLong() took 2,321 us on average
write byte[8] took 576 us on average

在我看来,您没有打开磁盘写入缓存。如果没有磁盘缓存,对于 5400 RPM 磁盘,我预计每次提交的写入大约需要 11 毫秒,即 60000 毫秒/5400 => 11 毫秒。

关于java - 为什么 RandomAccessFile writeLong 是通过多次写入调用实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5742427/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com