【问题标题】:Fast text reading (alternatives to File.ReadAllText() and/or StreamReader.ReadToEnd())快速文本阅读(File.ReadAllText() 和/或 StreamReader.ReadToEnd() 的替代品)
【发布时间】:2014-12-11 07:58:31
【问题描述】:

快速阅读问题:我想知道是否还有其他我忽略的技术,可能是 p/invoke 到某个库(无论是 winapi 还是第三方库)。欢迎所有建议。

问题的完整背景: 对于给定的用例,我需要将文本文件读入内存,然后我可以对其进行操作。问题不在于操作,而在于 I/O。我目前在 C# 中使用以下技术:

1)“文件”的ReadAllText()方法

var content = File.ReadAllText(file.FullName);

2) “StreamReader”的ReadToEnd()方法

var content = String.Empty;
using(var streamReader = File.OpenText(file.FullName)) {
    content = streamReader.ReadToEnd();
}

3) 我还尝试将BufferedStream 与方法 2 结合使用

对于 5 到 20MB 的文件,它们的性能大致相同。所以,那么问题来了:我想知道是否还有其他我忽略的技术,可能是 p/invoke 到某个库(无论是 winapi 还是第三方库)。欢迎所有建议。

【问题讨论】:

  • 这还不够快吗?文件不是那么大,所以我想知道如果当前方法可读且高效,为什么还要使用 winapi。如果它们真的很大,您可以使用MemoryMappedFile
  • @TimSchmelter 虽然我理解您的评论,但这与最初提出的问题无关,例如也许我不需要它,但其他人可能。但我理解你的意图,当然 winapi 或第三方调用可能会很混乱,但这是在实施时需要考虑的事情,或者不是。对于我的情况,这确实很重要,否则我不会求助于询问。如果没有解决方案,那么我会接受它:)。
  • 唯一的其他方法是:1) 在您的硬件中找到更好的 I/O 速率(将您的硬件替换为更好的东西)或 2) 为设备找到更好的 I/O 驱动程序。没有其他事情可以真正做到。
  • TimSchmelter 我将研究 MemoryMappedFile (msdn)。 @Ahmedilyas - 这确实是一个有效的观点,我们也可以对此进行测试。
  • @Tim 将整个文件放入托管内存时,映射不会更快。

标签: c# string performance text pinvoke


【解决方案1】:

您列出的所有变体的瓶颈都是 I/O。任何将完整文件从磁盘读取到内存的方法都会遇到同样的瓶颈。

因此,可以合理地得出结论,没有其他方法会产生显着收益。当然,您会发现这些方法和其他方法之间的性能略有不同。但是你永远不会看到数量级的收益。

【讨论】:

  • 这意味着所提供的方法已经是 .NET(甚至第三方解决方案)中读取文本文件的最快且性能最好的方法了?只是要求确定。因为我想知道为什么像 Notepad++ 这样的东西可以更快地读取这些文件.. :)?
  • @YvesSchelpe 我怀疑 Notepad++ 没有一次性将整个文件读入内存。它正在根据需要读取块。
  • 确实有效,在我的情况下我需要它。但我会接受这只是一个硬件限制,正如我所怀疑的那样,但我认为问一下也无妨。
  • Notepad++ 是否将整个文件读入内存然后显示?还是采取不同的方法?您还需要注意可能会混淆时间的磁盘缓存。如果文件在缓存中,读取文件总是更快。最后,Notepad++ 可能不必像在 .net 中那样将 8 位编码文本转换为 16 位。
  • @DavidHeffernan 确实如此。通过进一步的测试(仅在我的机器上),notepad++ 并没有那么快。我想,在阅读完整文件时,我的问题中列出的选项是必须解决问题的选项。
【解决方案2】:

我发现this 文章与该主题相关,您可能会对它感兴趣。

文章指出:

  • 将每一行读入一个字符串(缓冲或非缓冲)几乎总是比一次读取整个文本快,而且几乎总是比使用字符串生成器快。

  • 很多人表示,使用 BufferedReader 始终是最快的方法,根据他的测试,这有点错误。我在使用 BufferedReader 方面也有很好的经验,但这只是一种感觉,他的测试表明这并不总是最快的方式,有关更多信息,请查看文章。

您将在本文中找到 9 种不同的读取文本文件的技术的示例代码和测试结果,即使这没有向您展示“最快的方式”,它可能对您很有趣和有帮助。

【讨论】:

    【解决方案3】:
    File.ReadAllLines()
    

    提供更快的性能,但这取决于机器配置和文件大小。请参阅链接以获得良好的比较http://cc.davelozinski.com/c-sharp/fastest-way-to-read-text-files

    【讨论】:

    • 我发布并阅读了同一篇文章,确实这不是“最好”的技术,每行阅读几乎总是比一次阅读整个文本更快。
    • 就我而言,它也没有成为赢家,正如@DavidHeffernan 在文章中指出的那样。这篇文章本身读起来很有趣,它回答说没有其他选择可以替代我已经尝试过的内容:)。
    • @MeAndSomeRandoms 我知道,但我需要整个文件才能开始对内容应用逻辑。每行一行不是选项,否则确实......
    • 阅读后续article 测试读取和处理文件。在这里,我们有 2 个明显的赢家,您可能需要考虑使用 ReadAllLines() 进行读取并使用并行 for 循环进行处理。 Mahesh Malpani 的上述帖子有些正确!
    猜你喜欢
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多