如何提高大量较小的文件读写速度或性能

时间:2012-01-02 11:03:42

标签: c# .net performance io filesystems

昨天,我在这里问了一个问题:how do disable disk cache in c# invoke win32 CreateFile api with FILE_FLAG_NO_BUFFERING

在我的性能测试展示(写入和读取测试,1000个文件和总大小220M)中,FILE_FLAG_NO_BUFFERING无法帮助我提高性能并低于.net默认磁盘缓存,因为我尝试更改{{ 1}}到FILE_FLAG_NO_BUFFERING可以到达.net默认磁盘缓存,速度更快。

之前,我尝试使用mongodb的gridfs功能替换windows文件系统,不好(我不需要使用分布式功能,只需品尝)。

在我的产品中,服务器可以通过tcp / ip每秒获取大量较小的文件(60-100k),然后需要将其保存到磁盘,第三个服务读取这些文件一次(只读一次如果我使用异步I / O是否可以帮助我,是否可以获得最佳速度和最佳低CPU周期?有人可以给我建议吗?或者我仍然可以使用FileStream类?

更新1

内存映射文件是否可以实现我的需求。所有文件都写入一个或多个大文件并从中读取?

2 个答案:

答案 0 :(得分:3)

如果您的PC需要5-10秒才能将100kB文件写入磁盘,那么您要么拥有世界上最旧,最慢的PC,要么您的代码效率非常低。

关闭磁盘缓存可能会使事情变得更糟而不是更好。有了磁盘缓存,您的写入速度将会很快,而Windows将在稍后将数据刷新到磁盘的缓慢部分。实际上,增加I / O缓冲通常会导致I / O得到显着改善。

您肯定希望使用异步写入 - 这意味着您的服务器启动数据写入,然后返回响应其客户端,而操作系统处理在后台将数据写入磁盘。

应该不需要对写入进行排队(因为如果启用了光盘缓存,操作系统就已经这样做了),但如果所有其他方法都失败了,那么你可以尝试这样做 - 它只能写一个文件一次最小化磁盘搜索的需要..

通常对于I / O,使用较大的缓冲区有助于提高吞吐量。例如,不是在循环中将每个单独的字节写入文件,而是在一次写入操作中写入缓冲区数据(理想情况下是整个文件,对于您提到的大小)。这将最大限度地减少开销(而不是为每个字节调用一个写函数,为整个文件调用一次函数)。我怀疑你可能正在做这样的事情,因为这是我知道的唯一一种将性能降低到你建议的水平的方法。

内存映射文件对您没有帮助。他们非常适合访问大文件的内容。

答案 1 :(得分:1)

在您的情况下,一个错误的重大改进可以是,imo,处理文件而不用将它们保存到磁盘,之后,如果您确实需要存储它们,请将它们推送到{ {1}}并通过将它们保存在磁盘上来证明它在另一个线程中。通过这样做,您将毫不费力地获得所需的处理数据,而不会浪费时间将数据保存在磁盘上,但之后也会在磁盘上放置一个文件,而不会损失Queue的计算能力。