【发布时间】:2018-02-05 20:15:09
【问题描述】:
我今天遇到了一件关于RandomAccessFile 的有趣事情。
我注意到使用RandomAccessFile 的writeInt(int i) 方法比使用RandomAccessFile 的write(byte[] b) 慢得多,我首先将int 值转换为byte[4] 数组。
我正在用这段代码进行转换
private static byte[] intToByte(int i)
{
byte[] result = new byte[4];
result[0] = (byte) (i >> 24);
result[1] = (byte) (i >> 16);
result[2] = (byte) (i >> 8);
result[3] = (byte) (i);
return result;
}
差异非常显着,有利于write(byte[] b)。
使用 JDK 8 在我的笔记本电脑上写入 100 万个ints:
- 通过
writeInt(int i)方法耗时~9 秒 - 通过
write(byte[] b)耗时~2.3 秒
我在另一个环境中也有类似的结果,我使用的是 JDK 7 和完全不同的机器。
writeInt(int i) 方法委托给原生 write0(int b) 方法,write(byte[] b) 委托给原生 writeBytes。
当我进行分析时,我注意到大部分执行时间都花在了writeInt 方法上。
有谁知道为什么我看到了这么大的差异?似乎writeInt 的效率较低。
【问题讨论】:
-
反向调用这些方法怎么样?您可能已经用第一个加热了 JVM,只是用热 VM 调用了第二个。无论如何,JMH 的存在是有原因的,并且在这里受到如此多的赞誉;除非你真的发现了一些有趣的东西;)
-
感谢您的评论。我明白你在说什么,我会做 JMH 基准测试并返回结果。虽然我在“冷”JVM 上进行了两个测试,但在不同的运行中分别调用这些测试 - 结果相同。
-
明白,但同时你需要明确区分一些数字和一些有意义的数字。通过适当的 JMH 测试(这也不是在公园里散步),你的数字可能是有意义的......
-
好的,我有一些数字。测试源可以在这里找到github.com/kristoffSC/RafBenchmark/tree/master/src/main/java/… 似乎即使在 JMH 中 write(byte[] b) 也更快。结果可以在这里找到:github.com/kristoffSC/RafBenchmark/blob/master/JMH_Results.txt 不过有一件事 - 因为 raf.writeInt 和 raf.write(byte[] b) 方法没有返回任何值,所以我无法在这里使用 JMH blackhole。
-
如果你不是在两次写入之间寻找,只是顺序写入,你根本不应该使用
RandomAccessFile。DataOutputStreamaround aBufferedOutputStreamaround aFileOutputStream将快几个数量级。 RAF 用于错误的随机访问文件。它没有以任何方式进行优化。
标签: java file-writing randomaccessfile