【问题标题】:Fastest way to search ASCII files in C# for simple keywords?在 C# 中搜索 ASCII 文件以获取简单关键字的最快方法?
【发布时间】:2011-05-16 10:01:48
【问题描述】:

现在,我在 ASCII 文件中搜索简单的关键字,如下所示:

int SearchInFile (string file, string searchString)
{
    int num = 0;

    StreamReader reader = File.OpenText (file);
    string line = reader.ReadLine();

    while (line != null)
    {
        int count = CountSubstrings(line, searchString);
        if (count != 0)
        {
            num += count;
        }
        line = reader.ReadLine();
    }

    reader.Close();

    return num;
}

这是最快、最节省内存的方法吗?如果要对搜索方式产生巨大影响,则返回计数是可选的,但不是单独返回。

我是这样使用的:

SearchInFile ( "C:\\text.txt", "cool" );

【问题讨论】:

  • 你现在拥有的应该可以很好地用于大多数实际用途。

标签: c# .net performance io


【解决方案1】:

如果您真的想要更高的性能(处理大约数百 MB 或 GB 的文件),那么您应该按大约 1k 的块读取字符串并对其进行搜索,而不是逐行搜索.尽管必须处理一些边界条件,但这应该会更快。

话虽如此,您应该应用像 ANTS 这样的分析器来查看这是否真的是您的瓶颈。

【解决方案2】:

只需使用 StreamReader 的 ReadToEnd 方法将文本文件加载到一个大字符串中并使用 string.IndexOf():

string test = reader.ReadToEnd();

test.indexOf("keyword")

【讨论】:

  • 谢谢,你觉得会更快吗?我可以在明确之后立即清理内存吗?
  • 这可能会更快,但对于非常大的文件很危险,因为用户的计算机可能没有足够的内存。
  • @Joan 没有指定他想要搜索大文件。对于大文件,他必须使用一些特定的算法,如 Rabin–Karp 字符串搜索算法或 Boyer–Moore 算法。
  • 是的,取决于文件的大小。您可能还想使用 TPL 来并行读取/搜索行。您可以使用流水线模式将其设置为尽快运行。
  • “大”字符串和普通字符串有什么区别? :)
【解决方案3】:

在非托管代码中,性能方面最有效的方法是使用Memory-Mapped Files,而不是读取缓冲区中的文件。我确信只有通过这种方式才能获得最好的结果,特别是如果您要扫描的文件可能是来自远程存储的文件(来自服务器的文件)。

我不确定在您的情况下使用相应的 .NET 4.0 classes 是否会完全一样有效。

【讨论】:

  • 内存映射文件现在也可以在 .NET 中使用。 (.net 4.0)
  • @Eric Falsken:我知道内存映射文件现在可以在 .NET 4.0 中使用,请点击我回答的最后几句中的链接。但区别在于,在非托管代码中MapViewOfFile 为您提供一个表示(作为分页文件)文件的内存指针。您可以直接使用任何函数来使用指针搜索子字符串。在 .NET 中,CreateViewAccessorCreateViewStream 更多地被设计为用于读取文件的部分包含。所以在分配额外内存的过程中会产生更多的开销。
猜你喜欢
  • 2011-10-28
  • 2017-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多