- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在分析应用程序时,我注意到 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 msUsing 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/
目前,我有: outByte.writeInt(0x49492a00); outByte.writeInt(0x08000000); 但我希望能够将所有这些写在同一行上。但是: outByte.wri
在分析应用程序时,我注意到 RandomAccessFile.writeLong 花费了很多时间。 我查了下这个方法的代码,涉及8次native方法write的调用。我使用 byte[] 为 writ
本文整理了Java中java.util.zip.ZipOutputStream.writeLong()方法的一些代码示例,展示了ZipOutputStream.writeLong()的具体用法。这些代
我正在尝试使用 Java 命令为随机文件 IO 编写 Long,如下所示: fstreamOut = new FileOutputStream(new File("C:\\Basmah","dataO
我是一名优秀的程序员,十分优秀!