从Java中的文件中读取整数的最快方法是什么?

时间:2011-05-24 17:53:53

标签: java performance io

我有一个如下排列的整数文件:

1 2 3 55 22 11 (and so on)

我希望尽快读取这些数字,以减少程序的总执行时间。到目前为止,我使用的扫描仪效果很好。但是,我觉得我可以使用更快的IO实用程序。有谁能指出我正确的方向?

编辑:

所以是的,我确认我的程序中的IO通过在java代码周围设置不同的计时器并比较结果来花费最多的时间。

3 个答案:

答案 0 :(得分:9)

当前文件格式

如果数字表示为Strings,没有更快的方式来读取它们并解析它们,磁盘I / O将比CPU正在做的任何事情都要慢几个数量级。唯一可以做的是使用具有巨大缓冲区大小的BufferedReader并尝试在使用Scanner之前获取尽可能多的内存中的文件。

备用文件格式

如果您可以在文件中将它们表示为二进制文件并使用DataInputStream class读取数字,那么您可能会略微减少I / O时间并减少边际CPU数量,因为您不需要将String表示解析为int,除非您的输入文件为数百兆字节或更大,否则可能无法测量。 **缓冲输入流仍然比其他任何东西都更有效,在这种情况下使用BufferedInputStream

如何优化

您需要强大的分析功能,甚至可以检测您所做的任何更改是否会影响效果正面负面

如果你反复阅读同一个文件,操作系统磁盘缓存会使基准测试失误,操作系统会缓存它并搞砸你的基准测试。 足够好了解

  

“我们应该忘记小事   效率,约占97%   时间:过早优化是   万恶之源“ - Donald Knuth

Kunth引用的过早部分是重要的部分,它意味着:

如果没有分析和基准来验证您正在更改的内容实际上是瓶颈,并且您可以衡量更改的正面或负面影响,请不要进行优化。

Here is a quick benchmark比较读取同一组二进制数的BufferedInputStream与由Scanner支持的BufferedReader,将同一组数字与文本表示形式进行比较SPACE 1}}分隔符。

结果非常一致:

我的Core i3笔记本电脑上的1,000个数字,内存为8GB

Read binary file in 0001 ms
Read text file in   0041 ms

我的Core i3笔记本电脑上的1,000,000个数字,内存为8GB

Read binary file in 0603 ms
Read text file in   1509 ms

对于拥有8GB内存的Core i3笔记本电脑上的50,000,000个数字

Read binary file in 29020 ms
Read text file in   70346 ms

50,000,000个数字的文件大小如下:

 48M input.dat
419M input.txt

在数组变得非常大之前读取二进制文件要快得多。二进制编码的int上的I / O较少(大约10倍),没有String解析逻辑,以及对象创建的其他开销以及Scanner所做的任何其他开销。我继续使用BufferedInputStream类的Reader版本,因为这些是最佳做法,应尽可能使用。

对于额外的功劳,压缩会减少大文件上的I / O等待,对CPU时间几乎没有可测量的影响。

答案 1 :(得分:1)

通常,您可以像磁盘允许的那样快速读取数据。更快地阅读它的最好方法是使其更紧凑或获得更快的磁盘。

对于您使用的格式,我会GZip文件并读取压缩数据。这是提高读取基础数据的速率的简单方法。

答案 2 :(得分:-1)

升级可能性:

  • 购买更快的磁盘。
  • 购买ssd-drive。
  • 将文件存储在ramdisk中。

在获得更高的性能/速度方面总是需要权衡。上述方法将花费金钱,并且必须在每个主机上执行,因此如果这是一个销售给多个客户的程序,那么可以更好地选择算法,这将节省每个主机的费用,程序运行。

如果压缩文件或存储二进制数据,则读取速度会增加,但使用独立工具检查数据将更加困难。当然,我们无法判断这可能发生的频率。

在大多数情况下,我建议保留人类可读的数据,并使用较慢的程序,但当然这取决于您丢失的时间,丢失的频率,等等。

也许只是一个练习,要找出,你能得到多快。但是,我喜欢在不考虑权衡和成本的情况下,始终保持最高性能的习惯。