Advice on handling large data volumes因此,我有大量的"非常大"的ASCII数字数据文件(共计千兆字节),并且我的程序将需要至少顺序顺序地处理整个文件。 关于存储/加载数据的任何建议吗?我已经考虑过将文件转换为二进制文件,以使其更小并更快地加载。 我应该一次将所有内容都加载到内存中吗?
我是"内存映射的I / O"(又称"直接字节缓冲区")的忠实拥护者。在Java中,它们称为映射字节缓冲区,它们是java.nio的一部分。 (基本上,此机制使用操作系统的虚拟内存分页系统来"映射"您的文件,并以编程方式将它们作为字节缓冲区显示。操作系统将设法自动神奇地,非常快速地自动将字节移入磁盘和内存。 我建议使用这种方法,因为a)对我有用,b)让您专注于算法,并让JVM,OS和硬件进行性能优化。经常,他们比我们卑鄙的程序员更了解什么是最好的。 ;) 您如何在上下文中使用MBB?只需为每个文件创建一个MBB,然后阅读即可。您只需要存储您的结果。 。 BTW:您正在处理多少数据(以GB为单位)?如果它大于3-4GB,则在32位计算机上将无法使用,因为MBB实现是平台体系结构对可寻址内存空间的捍卫者。一台64位计算机 您可能想看看Wide Finder项目中的条目(在Google中搜索" wide finder" java)。 Wide finder涉及读取日志文件中的许多行,因此请查看Java实现,并查看在那里有效和无效的内容。 n 没有进一步了解正在进行的处理方式,以下是我做类似工作时的一些一般想法。 编写一个对数据集执行任意操作的应用程序原型(甚至可能"丢掉")。看看有多快。如果您能想到的最简单,最幼稚的事情是可以接受的快速,那就不用担心! 如果天真的方法不起作用,请考虑对数据进行预处理,以使后续运行将在可接受的时间内运行。您提到必须在数据集中"跳来跳去"很多。有什么办法可以对它进行预处理?或者,一个预处理步骤可以是生成更多数据-索引数据-提供有关数据集关键,必要部分的字节准确的位置信息。然后,您的主要处理运行可以利用此信息直接跳转到必要的数据。 因此,总而言之,我的方法是立即尝试一些简单的操作,然后查看性能。也许会没事的。否则,请考虑分多个步骤处理数据,以节省最昂贵的操作以进行不频繁的预处理。 不要"将所有内容加载到内存中"。只需执行文件访问,并让操作系统的磁盘页面缓存决定何时实际将内容直接从内存中拉出。 您可以转换为二进制,但是如果您需要保留原始数据,那么您将拥有1个数据副本。 在原始ascii数据之上构建某种索引可能是很实际的,因此,如果您需要再次浏览数据,则可以在以后的时间中更快地进行处理。 按顺序回答您的问题:
不是必须的。对于某些文件,您也许可以,但是如果您只是按顺序处理,则只需对所有内容进行某种缓冲的读取,并一路存储您需要的内容即可。
BufferedReaders / etc最简单,尽管您可以更深入地研究FileChannel / etc以使用内存映射的I / O一次浏览数据窗口。
这真的取决于您对数据本身的处理方式! n n 我建议强烈利用正则表达式,并研究"新的" IO nio包,以加快输入速度。然后,它应该会像您实际期望的那样以千兆字节的数据传输。 如果定期对数字数据进行采样并且需要进行随机访问,请考虑将其存储在四叉树中。 我发现Informatica是一个非常有用的数据处理工具。好消息是,最新版本甚至允许Java转换。如果您要处理的数据量为TB,那么可能是时候花点时间使用最好的ETL工具了。 我假设您想对此处的处理结果进行某些处理,例如将其存储在某个地方。 您确实没有给我们足够的信息来帮助您。您是否需要完整地加载每个文件才能进行处理?还是可以逐行处理它?<??pb> 一次加载整个文件可能会导致性能下降,即使文件不是很大也是如此。最好的选择是定义一个适合您的缓冲区大小,并一次读取/处理缓冲区中的数据。 |