System.IO.ReadAllxxx / WriteAllxxx方法的性能
Web上是否有System.IO.File.ReadAllxxx / WriteAllxxx方法与StreamReader / StremWriter类的性能比较。我们认为从.net 3.0中读取/写入文本文件的最佳方法(从性能角度来看)是什么?
当我检查System.IO.File类的MSDN页面时,在示例代码中MS正在使用StreamReader / StreamWriter进行文件操作。有什么特别的原因可以避免File.ReadAllxxx / WriteAllxxx方法,即使它们看起来更容易理解?
解决方案
File.ReadAllText和类似方法在内部使用StreamReader / Writers,因此性能应与我们自己做的事情相当。
我想说,尽可能使用File.XXX方法,它使代码a)易于阅读b)减少包含错误的可能性(无论我们编写自己的暗示)。
@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(); } }
如果我们打算支持加载/保存非常大的文件,则可能不想使用File.ReadAllxxx / WriteAllxxx。
换句话说,对于打算在编辑千兆字节大小的文件时保持可用状态的编辑器,我们希望使用StreamReader / StreamWriter进行设计并进行搜索,因此仅加载文件的可见部分。
对于没有这些(稀有)要求的任何内容,我会说走简单的路线,然后使用File.ReadAllxxx / WriteAllxxx。正如aku所显示的,它们只是在内部使用与我们手动编写代码相同的StreamReader / Writer模式。
除非我们正在执行诸如将多行匹配的正则表达式应用于文本文件之类的操作,否则通常希望避免使用ReadAll / WriteAll。以更易于管理的小块做事几乎总是会带来更好的性能。
例如,应该从小型数据库中读取数据库中的表并将其发送到客户端的Web浏览器,以利用小型网络消息的性质并减少处理计算机内存的使用。没有理由在Web服务器上的内存中缓冲10,000个记录并一次转储所有记录。文件系统也是如此。如果我们担心许多少量数据的写入性能,例如底层文件系统中用于分配空间的内容以及开销是多少,那么我们可能会发现这些文章很有启发性:
Windows文件缓存使用情况
文件读取基准
澄清:如果我们正在执行ReadAll,然后执行String.Split('\ r')以获取文件中所有行的数组,并使用for循环来处理每一行代码,这通常会导致更糟的情况性能,而不是逐行读取文件并在每一行上执行处理。如果我们有一些处理需要花费大量时间,并且通常比早些释放系统资源(文件句柄)更好,那么这并不是一个硬规则。但是,关于写入文件,与将其缓存在内存中相比,转储每个项目的任何转换过程(例如在大量项目上调用ToString())的结果几乎总是更好。
其他人已经解释了性能,所以我不会对其进行补充,但是我会补充说,当辅助方法不可用时,MSDN代码示例可能是在.NET 2.0之前编写的。
该链接具有读取50 + K行的基准,并指示流阅读器快40%。
http://dotnetperls.com/Content/File-Handling.aspx
这份MSR(Microsoft Research)论文是一个好的开始,它们还记录了许多点工具,例如IOSpeed,FragDisk等...,我们可以在环境中使用和测试它们。
我们还可以阅读更新的报告/演示,以了解如何最大程度地提高顺序IO。他们揭穿了非常有趣的东西,"移动HD磁头是最耗时的操作"神话,他们还完整记录了其测试环境和相关配置,包括主板,RAID控制器以及几乎所有可靠信息,供我们复制工作。其中一些亮点是Opteron / XEON的匹配方式,但随后他们还将它们与疯狂的,炒作的NEC Itanium(32或者64 proc或者类似)进行了比较。在这里的第二个链接中,我们可以找到有关如何测试和评估高通量场景和需求的更多资源。
同一研究主题中的其他MSR论文涉及如何最大程度地增加支出(例如RAM,CPU,磁盘Spindals等)以适应使用模式的指导……都很整洁。
但是,其中一些已过时,但无论如何,通常较旧的API都是较快/低级的API;)
我目前使用C#,C ++ / CLI,本机代码和位图缓存(rtl * bitmap)的混合,在专用的应用服务器上推送了数十万个TPS。
小心;