我有一些“大量”的ASCII格式的数值数据文件(总共占用几个GB),我的程序需要至少一次按顺序处理它们。
有关存储/加载数据的建议吗? 我考虑将文件转换为二进制格式,以使它们更小且加载速度更快。
我应该一次性将所有内容加载到内存中吗?
如果不是,那么部分加载数据的好方法是什么?
有哪些与Java相关的效率技巧?
我有一些“大量”的ASCII格式的数值数据文件(总共占用几个GB),我的程序需要至少一次按顺序处理它们。
有关存储/加载数据的建议吗? 我考虑将文件转换为二进制格式,以使它们更小且加载速度更快。
我应该一次性将所有内容加载到内存中吗?
如果不是,那么部分加载数据的好方法是什么?
有哪些与Java相关的效率技巧?
顺便问一下,你处理的数据量有多大,以GB为单位?如果超过3-4GB,32位机器上的MBB实现将依赖于平台体系结构可寻址内存空间,因此这对你来说行不通。64位机器和操作系统将使您达到1TB或128TB的可映射数据。
如果您考虑性能,那么要知道Kirk Pepperdine(一个有点出名的Java性能专家)。他参与了一个网站www.JavaPerformanceTuning.com,其中包含一些更多的MBB细节:NIO Performance Tips和其他Java性能相关内容。
您可以将数据转换为二进制,但如果需要保留原始数据,则会有1个或多个副本。
建议在原始ASCII数据上构建某种索引,这样如果需要再次处理数据,则可以更快地进行处理。
按顺序回答您的问题:
我应该一次性将所有内容加载到内存中吗?
如果不必要,最好不要这样做。对于某些文件,您可能能够这样做,但如果仅按顺序处理,请逐个缓冲读取,沿途存储所需内容即可。
如果不这样做,部分加载数据的良好方法是什么?
BufferedReader /等最简单,尽管您可以深入研究FileChannel /等,使用内存映射I/O以按窗口方式浏览数据。
有哪些Java相关的效率提示?
这实际上取决于您对数据本身的操作!
没有任何关于正在进行的处理类型的额外见解,以下是我在做类似工作时的一些一般想法。
编写应用程序的原型(甚至可以是“一次性使用”),对数据集执行任意操作。看看它有多快。如果你能想到的最简单、最天真的方法足够快,那就没问题了!
如果天真的方法不起作用,请考虑预处理数据,以便后续运行在可接受的时间内运行。你提到必须在数据集中“跳来跳去”。有没有办法将其预处理掉?或者,一个预处理步骤可以生成更多的数据 - 索引数据 - 提供关键、必要部分的字节精确位置信息。然后,你的主处理运行可以利用这些信息直接跳转到必要的数据。
因此,总结一下,我的方法是现在尝试一些简单的东西,看看性能如何。也许会很好。否则,研究一下将数据分步处理,将最昂贵的操作保存为不频繁的预处理。
不要“将所有东西加载到内存中”。只需执行文件访问操作,让操作系统的磁盘页面缓存决定何时实际从内存中直接提取内容。这在很大程度上取决于文件中的数据。大型主机已经进行顺序数据处理很长时间了,但它们通常不使用随机访问数据。它们只是一次读取一行并处理相应数量的数据,然后继续。
对于随机访问,通常最好建立具有缓存封装器的对象,这些封装器知道需要构造的数据在文件中的位置。当需要时,它们读取该数据并构造自己。这样,当内存不足时,您可以开始杀掉一些东西,而不必太担心以后无法恢复。
你并没有给我们足够的信息来帮助你。你需要一次性加载每个文件以便处理吗?还是可以逐行处理?
一次性加载整个文件很可能会导致性能不佳,即使对于那些不是特别大的文件也是如此。你最好定义一个适合自己的缓冲区大小,并一次读取/处理一定量的数据。
我发现Informatica是一款非常有用的数据处理工具。好消息是,最近的版本甚至允许Java转换。如果你正在处理数千兆字节的数据,那么现在可能是时候投资于最佳ETL工具了。
我假设您想在此处对处理结果进行某些操作,例如将其存储在某个地方。