2

System.IO.File.ReadAllxxx / WriteAllxxx 方法与 Web 上的 StreamReader / StremWriter 类是否有任何性能比较。您认为在 .net 3.0 中读取/写入文本文件的最佳方式(从性能角度来看)是什么?

当我检查System.IO.File 类的 MSDN 页面时,在示例代码中 MS 使用 StreamReader / StreamWriter 进行文件操作。是否有任何具体原因避免使用 File.ReadAllxxx / WriteAllxxx 方法,即使它们看起来更容易理解?

4

7 回答 7

5

如果您打算支持加载/保存非常大的文件,您可能不想使用 File.ReadAllxxx / WriteAllxxx。

换句话说,对于您打算在编辑千兆字节大小的文件时保持可用的编辑器,您需要一些带有 StreamReader/StreamWriter 和搜索的设计,因此您只加载文件中可见的部分。

对于没有这些(罕见)要求的任何事情,我会说采取简单的方法并使用 File.ReadAllxxx / WriteAllxxx。它们只是在内部使用与您手动编码相同的 StreamReader/Writer 模式,正如 aku 所示。

于 2008-10-03T12:07:12.727 回答
4

File.ReadAllText 和类似方法在内部使用 StreamReader/Writers,因此性能应该与您自己执行的任何操作相当。

我会说尽可能使用 File.XXX 方法,它使您的代码 a) 更易于阅读 b) 不太可能包含错误(在您自己编写的任何 impl 中)。

于 2008-10-03T11:52:14.163 回答
1

除非您正在执行某些操作,例如将多行匹配的正则表达式应用于文本文件,否则您通常希望避免 ReadAll/WriteAll。以更小更易于管理的块来做事几乎总能带来更好的性能。

例如,从数据库中读取表格并将其发送到客户端的 Web 浏览器应该在小集合中完成,这利用了小型网络消息的性质并减少了处理计算机内存的使用。没有理由在 Web 服务器的内存中缓冲 10,000 条记录并一次全部转储。文件系统也是如此。如果您关心许多少量数据的写入性能 - 例如底层文件系统中用于分配空间的内容以及开销是什么 - 您可能会发现这些文章很有启发性:

Windows 文件缓存使用情况

文件读取基准

澄清:如果您正在执行 ReadAll 后跟 String.Split('\r') 以获取文件中所有行的数组,并使用 for 循环处理每一行代码,这通常会导致更糟性能比逐行读取文件并在每一行上执行您的过程。这不是一个硬性规定——如果您有一些处理需要花费大量时间,通常最好尽快释放系统资源(文件句柄)。然而,在写入文件方面,将任何转换过程的结果(例如在大型项目列表上调用 ToString() )每个项目转储几乎总是比将其缓冲在内存中更好。

于 2008-10-03T12:13:58.877 回答
1

这篇MSR (Microsoft Research) 论文是一个好的开始,他们还记录了许多点工具,例如 IOSpeed、FragDisk 等……您可以在您的环境中使用和测试这些工具。

您还可以阅读有关如何最大化顺序 IO的更新报告/演示文稿。非常有趣的东西,因为他们揭穿了“移动 HD 磁头是最耗时的操作”的神话,他们还完整记录了他们的测试环境和相关配置,包括主板、raid 控制器和几乎所有相关信息,供您复制他们的工作。一些亮点是 Opteron / XEON 是如何匹配的,但他们随后还将它们与疯狂\炒作的 NEC Itanium(32 或 64 proc 或其他东西)进行了比较。从这里的第二个链接,您可以找到更多关于如何测试和评估高吞吐量场景和需求的资源。

在同一研究主题中的其他一些 MSR 论文涉及关于在哪里最大化您的支出的指导(例如 RAM、CPU、磁盘 Spindals ......等)以适应您的使用模式......所有这些都非常简洁。

然而,其中一些已经过时了,但通常较旧的 API 无论如何都是更快/低级的;)

我目前使用 C#、C++/CLI、本机代码和位图缓存 (rtl*bitmap) 的组合在专用的应用服务器上推送数十万 TPS。

小心;

于 2009-05-15T06:33:32.847 回答
0

其他人已经解释了性能,所以我不会添加它,但是我会补充一点,当辅助方法不可用时,MSDN 代码示例很可能是在 .NET 2.0 之前编写的。

于 2008-10-03T12:38:02.900 回答
0

@Fredrik Kalseth 是对的。File.ReadXXX 方法只是 StreamReader 类的方便包装器。

例如这里是File.ReadAllText的一个实现

public static string ReadAllText(string path, Encoding encoding)
{
    using (StreamReader reader = new StreamReader(path, encoding))
    {
        return reader.ReadToEnd();
    }
}
于 2008-10-03T12:05:27.817 回答
0

此链接具有读取 50+K 行的基准,并表明流式阅读器的速度大约快 40%。

http://dotnetperls.com/Content/File-Handling.aspx

于 2008-10-04T03:44:05.940 回答