Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.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#_Windows_Performance - Fatal编程技术网

C# 使用线程技术提高磁盘读取性能(多个文件)

C# 使用线程技术提高磁盘读取性能(多个文件),c#,windows,performance,C#,Windows,Performance,我需要找到一种方法,尽可能快地读取大量小文件(约300k文件) 使用FileStream按顺序读取它们并在一次调用中读取整个文件需要170到208秒(您知道,重新运行时,磁盘缓存会起作用,时间会有所不同) 然后我尝试将PInvoke与CreateFile/ReadFile一起使用,并使用FILE\u FLAG\u SEQUENTIAL\u SCAN,但我不喜欢任何更改 我尝试了几个线程(将大的一组线程分成几块,让每个线程都读它的一部分),这样我就可以稍微提高速度(如果每个新线程最多4个,甚至不能

我需要找到一种方法,尽可能快地读取大量小文件(约300k文件)

使用FileStream按顺序读取它们并在一次调用中读取整个文件需要170到208秒(您知道,重新运行时,磁盘缓存会起作用,时间会有所不同)

然后我尝试将PInvoke与CreateFile/ReadFile一起使用,并使用FILE\u FLAG\u SEQUENTIAL\u SCAN,但我不喜欢任何更改

我尝试了几个线程(将大的一组线程分成几块,让每个线程都读它的一部分),这样我就可以稍微提高速度(如果每个新线程最多4个,甚至不能提高5%)


关于如何找到最有效的方法,你有什么想法吗?

我的猜测是,你将受到低级文件访问代码、物理磁盘活动等的限制。多个线程可能最终会对磁盘造成冲击。您对这些文件的位置有多大的控制,以及创建这些文件时会发生什么

你能把它们安排在固态磁盘上而不是物理磁盘上吗


你能在数据到达时将其加载到数据库中吗。那么您的搜索将跨越一个(可能是索引的)数据库?

正如@djna告诉您的那样,您的磁盘一次可能只能为一个线程提供服务,因此程序中的多个线程没有帮助,实际上可能会使事情变得更糟。单线程版本代码的执行时间差异似乎远远超过了多线程节省的时间。换句话说,执行时间明显改善的统计显著性为0

您可能考虑的一个选项是移动到一个并行的I/O系统,该系统是为多线程访问而设计的。然而,这是一个很大的进步,只有当你定期做这种手术时才合适


另一种选择是在联网系统的本地磁盘上分发文件,并让每个系统通过部分文件工作。实现这一点对您来说是多么容易,您没有告诉我们足够多的信息,让我们在这方面给出好的建议,所以请考虑一下。

我将加载所有文件一次,另存为一个大文件。然后,您的应用程序可以只加载一个文件,并仅扫描300k文件中已更改的文件(按大小、修改日期或删除/添加),将这些更改应用于内存中的大文件

你说它们是小文件,所以我假设300k文件可以一次全部加载-如果不是,那么你必须只需要原始300k文件的一个子集,所以大文件可以就是那个子集


唯一不起作用的方法是,如果每次应用程序运行时都有其他东西在写入300k文件,这听起来不太可能。

假设您正在读取常规HDD,那么使用的线程越多,物理磁盘头就越需要寻找不同的磁道,而不是一次只返回一个文件。因此,除了在后台线程上执行这项工作以使应用程序在主线程上保持响应外,我还避免了任何多线程。另外,看看你的硬盘规格:一旦你达到了最大持续吞吐量,再多的代码调整也无济于事——你需要更多的硬件。Jono做到了。磁盘驱动器上的硬件有限。获得最大吞吐量的方法是最大限度地减少磁头移动所浪费的时间,因此一次只能读取一个文件。如果您可以安排每个文件在磁盘上是连续的,这应该会有所帮助。