如何在大文件上有效使用文件输入/输出函数(使用有限大小的内存)

时间:2015-12-28 08:40:53

标签: c++ algorithm performance file-io memory-mapped-files

我想在C ++上实现一种算法,它包含许多文件i / o。虽然我已经在较小的尺度上实现了类似的东西,但这次我需要处理几GB的文件。我知道当文件大小大于可用内存大小时,我应该考虑一些新的东西,我也应该关注成本。

我的计划是获取分配的内存大小并将其用于读取预定部分将结果保存在txt文件通过。但是,我需要在每次传递后逐行读取和修改生成的txt文件以更新它,因为生成的txt文件将是一个链表(字节块将对应于节点)。 / p>

将这些传递的结果保存在txt文件上并为每次传递逐行更新是否有效?如果您能告诉我任何可以使算法更有效的更改,我将不胜感激。我还要感谢你能写一些简短/快速的例子,因为我从未使用文件输入输出而不是"读完整个文件","把它写成整个文件"命令类型。

编辑: 操作系统是Linux和Mac OS。

在二进制文件中有许多字节段重复,我想对某些组合重复的次数进行排序。例如,如果二进制文件是111111100000001110101010100000111,我将计算某些预定模式(例如110111001010,10101011等)的出现次数并对它们进行排序。我期望的最小文件大小为1GB,最大大小为10-20GB。我将寻找大约1,000,000,000个模式,我将对它们进行排序。所以我想,因为每次我的缓冲区已满时我都需要更新输出文件,我不妨把它作为链表并更新列表(应该是~O(n))以避免快速排序(应该是〜 nlog(n))在最后。

1 个答案:

答案 0 :(得分:2)

这是一种有效的方法:

打开源文件并使用mmap()访问您的数据。这样您就可以直接访问OS disk-cahe消除将内存kernel mode复制到user mode。如果您的文件非常大,最好使用较小的mmapp-ed views来阻止创建大型页表。

根据您使用的不同模式的数量,您有以下选项:

如果模式的数量足够小以适应内存

  • 如果值很稀疏:将它们存储在带有模式/计数对的map中。
  • 如果值有些连续,请将计数存储在vector中,其中位置是模式的值,如果需要,则根据偏移量。

如果模式的数量可以变大

(你说的是10亿个模式 - 取决于它们的独特性),你可以创建一个mmap-ed outputfile并在那里存储计数,但要确保所有的值(或对)都是相同的宽度,即以二进制形式存储所有内容(您可以像使用数组一样使用它)。

如果大多数值是不同的,请将它们存储在模式值的位置 - 例如,如果模式(32位?)+计数为8个字节,则将它们存储在位置pattern-value * 8以便快速访问。如果您的模式值存在较大间隙,但您想避免插入移动数据,请考虑使用(临时)sparse file将值直接存储在正确的位置。

如果你只需要一个计数,你可以只在他们的特定位置存储计数(32位),但是如果你需要一个排序,你也会以某种方式需要模式值。

要对它们进行排序,我更倾向于使用radix sort