【发布时间】:2010-11-15 18:48:28
【问题描述】:
我希望对大文件 (> 4GB) 应用 KMP(或类似)搜索。
我预计这会给我带来问题。我无法将其全部复制到内存中,因为那里没有足够的空间。
我的问题是,进行此搜索的最佳方式是什么?我应该简单地创建一个 FILE* 并直接在文件中进行搜索,我应该将块(比如 4k)复制到内存并搜索那些,还是完全其他的?
【问题讨论】:
我希望对大文件 (> 4GB) 应用 KMP(或类似)搜索。
我预计这会给我带来问题。我无法将其全部复制到内存中,因为那里没有足够的空间。
我的问题是,进行此搜索的最佳方式是什么?我应该简单地创建一个 FILE* 并直接在文件中进行搜索,我应该将块(比如 4k)复制到内存并搜索那些,还是完全其他的?
【问题讨论】:
直接在文件中搜索会很慢,使用缓冲会提供更好的性能。但是请注意,您的缓冲区必须大于您搜索的内容 (SearchLength),当然,您必须在缓冲区结束前刷新缓冲区为 SearchLength 字节。
【讨论】:
最好的方法是分块阅读并搜索。您应该将块大小作为参数,这样您就可以试验什么可以提供最佳性能。
但是,尝试以某种方式索引文件通常更有效,这样您就不必线性搜索整个文件。例如,KMP 是一种字符串搜索算法——您只是在寻找单词的出现吗?然后,您可以只创建单词的哈希表(在磁盘上)及其在文件中的位置,并进行非常有效的搜索。
【讨论】:
如果您使用的是支持它的平台,则可以使用 mmap()。 文件的分页也是可以的,但是记得尽量保持缓冲区大以减少IO开销,并且要注意两个页面的边界(假设一个字符串是匹配的,但是被页面边界分割了)
另外,我建议您建立某种索引,并使用索引来限制搜索。 KMP 搜索并不是特别有效。这当然取决于您的文件的性质、它是如何创建的,等等。
【讨论】:
对于文件访问,我建议使用内存映射文件来避免数据复制。在 unix 机器上是微不足道的。如果不能在一个块中分配文件映射,您可能必须将其拆分为较小的块。如果您有兴趣,我可以提供一些代码。
对于搜索,我建议使用Boyer More search algorithm。
【讨论】: