我正在分析正在加载二进制文件的代码。加载时间约为15秒。
我的大部分加载时间来自加载二进制数据的方法。
我有以下代码来创建我的DataInputStream:
is = new DataInputStream(
new GZIPInputStream(
new FileInputStream("file.bin")));
我改为:
is = new DataInputStream(
new BufferedInputStream(
new GZIPInputStream(
new FileInputStream("file.bin"))));
所以在我做了这个小修改后,加载代码从15秒变为4.
但后来我发现BufferedInputStream有两个构造函数。另一个构造函数允许您显式定义缓冲区大小。
我有两个问题:
答案 0 :(得分:8)
GZIPInputStream和BufferedInputStream都使用内部缓冲区。这就是为什么在GZIPInputStream中使用BufferedInputStream不会带来任何好处。 GZIPInputStream的问题在于它不会缓冲它生成的输出,因此您当前的版本要快得多。
BufferedInputStream的默认缓冲区大小为8kb,因此您可以尝试增加或减少它以查看它是否有帮助。我怀疑确切的数字很重要,所以你可以简单地乘以或除以2。
如果文件很小,您也可以尝试完全缓冲它。这应该在理论上给你最好的表现。您还可以尝试增加GZIPInputStream的缓冲区大小(默认为512字节),因为这可能会加快从磁盘读取的速度。
答案 1 :(得分:4)
不要打扰编码二进制搜索。只需手动尝试一些值并比较时间(如果您愿意,可以进行手动二分查找)。您很可能会发现,各种各样的缓冲区大小都会为您提供接近最佳的性能,因此请选择最小的缓冲区。
您拥有的是正确的订单:
is = new DataInputStream(
new BufferedInputStream(
new GZIPInputStream(
new FileInputStream("file.bin"))));
将BufferedInputStream
置于GZIPInputStream
内是没有意义的,因为后者已经缓冲了它的输入(但不是输出。)
删除GZIPInputStream
可能是一个胜利,但如果必须从磁盘读取数据并且不驻留在文件系统缓存中,则很可能对性能有害。原因是从磁盘读取速度非常慢,解压缩gzip
非常快。因此,从磁盘读取较少数据并在内存中解压缩通常比从磁盘读取更多数据更便宜。