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

标签 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 默认磁盘缓存,因为我尝试将 FILE_FLAG_NO_BUFFERING 更改为 FILE_FLAG_SEQUENTIAL_SCAN 可以到达 .net 默认磁盘缓存并且速度更快。

之前,我尝试用mongodb的gridfs特性代替windows文件系统,效果不佳(而且我不需要使用分布式特性,只是尝尝)。

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

更新 1

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

最佳答案

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

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

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

应该不需要对写入进行排队(因为如果启用了磁盘缓存,操作系统将已经这样做了),但如果其他所有方法都失败了,您可以尝试这样做——它可能会通过只写入一个来提供帮助一次文件以尽量减少磁盘查找的需要..

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

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

关于c# - 如何提高大量较小文件的读写速度或性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8700066/

相关文章:

c# - 使用 RelativeSource 和 AncestorType 的 WPF 数据绑定(bind)

javascript - 如何在jquery的drop方法中调用函数?

mysql - 在连接的情况下是否对条件进行分组在 SQL 中是否重要?

c# - 创建一个匹配反射类型的方法

c# - 如何正确地将 Dictionary<Tuple<string,string>,Object> 作为参数传递给方法

c# - GraphQL 并行异步查询 c# EF Core 3.0

c# - Gtk.ListStore 中的虚拟模式?

.net - 为什么 .NET 中不需要 Maven?

.net - 从 Windows 服务中杀死一个进程

android - "Buttery""pre-butter"Android 中的 fragment 动画