Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何提高大量较小文件的读写速度或性能_C#_.net_Performance_Io_Filesystems - Fatal编程技术网

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

C# 如何提高大量较小文件的读写速度或性能,c#,.net,performance,io,filesystems,C#,.net,Performance,Io,Filesystems,昨天,我在这里问了一个问题: 在我的性能测试节目(写和读测试,1000个文件,总大小220M)中,FILE\u标志\u NO\u BUFFERING不能帮助我提高性能并降低.net默认磁盘缓存,由于我尝试将FILE\u FLAG\u NO\u BUFFERING更改为FILE\u FLAG\u SEQUENTIAL\u SCAN可以访问.net默认磁盘缓存,而且速度更快 以前,我尝试使用mongodb的gridfs功能替换windows文件系统,这并不好(而且我不需要使用分布式功能,只需要尝试一

昨天,我在这里问了一个问题:

在我的性能测试节目(写和读测试,1000个文件,总大小220M)中,
FILE\u标志\u NO\u BUFFERING
不能帮助我提高性能并降低.net默认磁盘缓存,由于我尝试将
FILE\u FLAG\u NO\u BUFFERING
更改为
FILE\u FLAG\u SEQUENTIAL\u SCAN
可以访问.net默认磁盘缓存,而且速度更快

以前,我尝试使用mongodb的gridfs功能替换windows文件系统,这并不好(而且我不需要使用分布式功能,只需要尝试一下)

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

更新1


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

在您的情况下,最错误和显著的改进之一是,依我看,可以在不将文件保存到磁盘的情况下处理这些文件,如果您确实需要存储它们,将它们推送到
队列上
,并通过将它们保存在磁盘上在另一个线程中验证。通过这样做,您将立即获得所需的已处理数据,而不会浪费时间将数据保存到磁盘上,同时也将在磁盘上保存一个文件,而不会损失
文件处理器的计算能力

如果您的电脑将100kB的文件写入磁盘需要5-10秒,那么您要么拥有世界上最旧、速度最慢的电脑,或者您的代码正在执行一些非常低效的操作

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

您肯定希望使用异步写入—这意味着您的服务器开始数据写入,然后在操作系统在后台将数据写入磁盘时返回到对其客户机的响应

应该不需要对写入进行排队(因为如果启用了磁盘缓存,操作系统已经在这样做了),但如果所有其他操作都失败,您可以尝试这样做-一次只写入一个文件可能会有帮助,从而最大限度地减少对磁盘的需求

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


内存映射文件对您没有帮助。它们最适合访问大型文件的内容。

如果只处理一次,是否真的有必要将这些文件写入磁盘?只需转到您的问题并通过选中anwes旁边的“右箭头”标记帮助您完成任务的答案…:-)@Pankaj Upadhyay,谢谢,我解决了。我会注意到。从你对Tigran的帖子的评论中可以清楚地看出,你试图解决的问题是错误的。你必须限制客户端,阻止他们以比你所能处理的更高的速度上传文件。如果这是不可接受的,那么你需要在问题上抛出硬件。嗨,@蒂格兰,在我考虑使用队列之前。但是,客户端在多线程中第二次发送20-30个文件,如果很多文件保存在内存中,服务器处理一个文件需要经过5-10秒。将引发memoryleak异常。您可以从一个位置将另一个线程加载到
队列中
,然后保存到磁盘并从队列中删除。不要填充所有和后处理,而是在运行期间进行处理。嗨,@Jason Williams,谢谢你的建议。这让我明白了该怎么做,谢谢。