在文本文件中搜索字符串的更快方法[关闭]

Posted

技术标签:

【中文标题】在文本文件中搜索字符串的更快方法[关闭]【英文标题】:Faster way of searching a string in text files [closed] 【发布时间】:2013-01-27 10:51:33 【问题描述】:

我需要使用 C# 在一组文本文件中搜索大约 13 个字符的字符串。文本文件的数量在变化,范围在 100-1000 之间。文件的大小可以在 1KB 到 10MB 之间。

我尝试了打开每个文件的幼稚方式,逐行读取并查看字符串是否存在(使用index.of),但这太慢了。我还尝试使用 Boyer-Moore 算法,该算法确实将时间缩短了 5 秒,但仍然感觉很慢。

关于如何加快搜索速度的任何想法?

【问题讨论】:

您的减速可能来自逐行读取文件。一次将文件全部读入内存并进行搜索。 ***.com/questions/4289353/… 是否需要多次搜索同一个文件? 【参考方案1】:

根据您想要进行“搜索”的次数,您是否想要使用搜索引擎。如果您想搜索很多次,请使用搜索引擎,否则:不要。我将在此处描述如何实现这两种场景。

使用搜索引擎时:听起来您正在寻找子字符串,这意味着您应该使用自己喜欢的搜索引擎来索引您的文件,最好是您可以自定义的引擎(lucene、terrier 等)。您在这里需要的技术是索引三元组,即:所有 3 字符组合都必须被索引。 F.ex.: 'foobar' 将生成 'foo','oob','oba' 和 'bar'。搜索时,您希望对查询执行相同操作,并使用所有这些三元组的 AND 发出搜索引擎查询。 (这将在文档中的发布列表上运行合并连接,这将返回他们的 ID 或您在发布列表中放置的任何内容)。

或者,您可以实现后缀数组并对文件进行一次索引。如果您想搜索短(1-2 个字符)子字符串,这将提供更多的灵活性,但就索引而言更难维护。 (在 CWI/Amsterdam 有一些关于快速索引后缀数组的研究)

当您只想搜索几次时,要使用的算法是 Boyer-Moore(我通常使用 [Graham A. Stephen,字符串搜索] 中所述的 Boyer-moore-sunday)或编译后的 DFA(您可以从 NFA 构造它们,这更容易制作)。但是,这只会给您带来一点速度提升,原因很简单,磁盘 IO 可能是您的瓶颈,并且比较您无论如何都需要解码的一堆字节非常快。

您可以做出的最大改进不是逐行读取文件,而是分块读取。如果可以的话,您应该将 NTFS 配置为使用 64 KB 的块大小,并以 64 KB 的倍数读取文件 - 一次读取时考虑 4 MB 或更多。我什至建议使用异步 IO,以便您可以同时读取和处理(以前读取的数据)。如果你做得正确,那应该已经在大多数现代硬件上为你提供了 10 MB 的瞬间实现。

最后但并非最不重要的一点是,在整个信息检索中使用的一个巧妙技巧也是使用快速压缩算法来压缩您的数据。由于磁盘 IO 比内存/cpu 操作慢,这可能也会有所帮助。 Google 的 Snappy 压缩器是快速压缩算法的一个很好的例子。

【讨论】:

【参考方案2】:

您可以使用 Microsoft 的索引服务来搜索要添加到目录中的文件夹中的文档。 Here 是一篇非常好的文章,您可以使用它来搜索您的文本文件

【讨论】:

【参考方案3】:

如果您的计算机可以处理它,请尝试将所有文​​本文件加载到内存中(使用technique shown here,然后评估内存中的文本。

如果您不能一次处理所有文件,请对最小的文件执行此操作。文件 I/O 将是您最大的开销,因此您希望尽可能减少它。

【讨论】:

【参考方案4】:

想到两个选项:

读取内存中的文本文件并一次搜索整个字符串。

如果这被证明太慢或太占用内存,请使用像 Apache Lucene 这样的索引器。有一个可用于 .NET 的简单易用的 SDK,称为 Lucene.net

这里对其做一个小介绍: http://www.codeproject.com/Articles/29755/Introducing-Lucene-Net

【讨论】:

【参考方案5】:

您应该考虑对内容使用操作系统文件搜索。看看Microsoft Windows Search 3.x SDK

或者您可以利用 PLINQ 在文件数组中进行搜索。请参阅此链接:

File Content and Directory Search using Directory.GetFiles and PLINQ

【讨论】:

不是投反对票,但我可以理解:你只是在制作一个与 PLINQ 并行的愚蠢解决方案(基本上是 IndexOf),这并不是一个好的解决方案 - 你基本上只是在抛出更多硬件,从而使其更快。这就像告诉那个人在多个线程中读取和处理他的文件。按照他的建议使用boyer-moore 比这要好得多。此外,我不确定 MS Search 是否支持自定义标记化,这似乎是一项要求。所以,在我看来,作为一名搜索专家,这里有比你更好的答案。抱歉……我很感激你的好意。 太棒了! PLINQ 太棒了!只有几行!我改用 ReadAllText,这是最快的。

以上是关于在文本文件中搜索字符串的更快方法[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在文本文件中搜索字符串 [关闭]

PowerShell5。查找/替换文本。 Switch和.NET框架或cmdlet和管道?哪个更快?哪个更容易阅读?

如何在 C# 中以编程方式搜索 PDF 文档 [关闭]

***列表和字典在底层中 谁更快***

在 .sql 文件中查找和替换文本

Python:从文本文件中逐字符创建一个字符串数组[关闭]