Waf*_*les 2 java io performance
我有一个整数文件,如下所示:
1 2 3 55 22 11 (and so on)
Run Code Online (Sandbox Code Playgroud)
我希望尽快读取这些数字,以减少程序的总执行时间.到目前为止,我使用的扫描仪效果很好.但是,我觉得我可以使用更快的IO实用程序.有谁能指出我正确的方向?
编辑:
所以是的,我确认我的程序中的IO通过在java代码周围设置不同的计时器并比较结果来节省大部分时间.
小智 9
当前的文件格式
如果数字表示为Strings没有更快的方式来读取它们并解析它们,那么磁盘I/O将比CPU正在做的任何事情都慢几个数量级.唯一可以做的是使用BufferedReader具有巨大缓冲区大小的a,并且在使用之前尝试获取尽可能多的内存中的文件Scanner.
备用文件格式
如果您可以在文件中将它们表示为二进制文件并使用DataInputStream 该类读取数字,那么您可能会略微减少I/O时间并减少边际CPU,因为您不需要将String表示解析为int可能的除非输入文件的数百兆字节或更大,否则无法测量.**缓冲输入流仍将比其他任何东西都更有效,BufferedInputStream在这种情况下使用a .
如何优化
您需要强大的分析功能,甚至可以检测您所做的任何更改是否会对性能产生正面或负面影响.
如果你反复阅读同一个文件,操作系统磁盘缓存之类的东西会使基准测试产生偏差,操作系统会缓存它并搞砸你的基准测试.了解什么是好的,早于晚.
"我们应该忘记小的效率,大约97%的时间说:过早的优化是所有邪恶的根源" - 唐纳德·克努特
Kunth引用的早期部分是重要的部分,它意味着:
如果没有分析和基准测试来验证您正在更改的内容实际上是瓶颈,并且您可以衡量更改的正面或负面影响,请不要进行优化.
这里是一个快速的基准进行比较的BufferedInputStream阅读同一组二进制数与一个Scanner由支持BufferedReader同一组中读取数字作为一个文本表示SPACE分隔符.
结果非常一致:
我的Core i3笔记本电脑上的1,000个数字,内存为8GB
Read binary file in 0001 ms
Read text file in 0041 ms
Run Code Online (Sandbox Code Playgroud)
我的Core i3笔记本电脑上的1,000,000个数字,内存为8GB
Read binary file in 0603 ms
Read text file in 1509 ms
Run Code Online (Sandbox Code Playgroud)
对于我的Core i3笔记本电脑上的50,000GB数字,内存为8GB
Read binary file in 29020 ms
Read text file in 70346 ms
Run Code Online (Sandbox Code Playgroud)
50,000,000个数字的文件大小如下:
48M input.dat
419M input.txt
Run Code Online (Sandbox Code Playgroud)
在数组变得非常大之前读取二进制文件要快得多.二进制编码的int上的I/O较少(约10倍),没有String解析逻辑,以及对象创建的其他开销以及其他任何Scanner操作.我继续使用和类的Buffered版本,因为这些是最佳实践,应该尽可能使用.InputStreamReader
对于额外的功劳,压缩会减少大文件上的I/O等待,对CPU时间几乎没有可测量的影响.