我需要找到一种方法来尽快读取大量小文件(大约300k文件)。
使用FileStream按顺序读取它们并在一次调用中读取整个文件需要170到208秒(你知道,重新运行,磁盘缓存起作用,时间也不同)。
然后我尝试将PInvoke与CreateFile / ReadFile一起使用并使用FILE_FLAG_SEQUENTIAL_SCAN,但我不理解任何更改。
我尝试了几个线程(将大块分成块并让每个线程都读取它的部分)这样我就能够稍微提高速度(每个新线程最多只能达到4%)
关于如何找到最有效的方法的任何想法?
答案 0 :(得分:2)
正如@djna告诉你的那样,你的磁盘可能一次只能为一个线程服务,所以程序中的多个线程无法帮助,实际上可能会让事情变得更糟。单线程版本代码的执行时间差异似乎远远超过了多线程节省的时间。换句话说,执行时间明显改善的统计显着性为0。
您可能考虑的一个选项是迁移到专为多线程访问而设计的并行I / O系统。然而,这是一个很大的进步,只有在您定期进行此类操作时才适用。
另一个选择是在联网系统上的本地磁盘上分发文件,并让每个系统都通过一部分文件。你实现这个是多么容易,你没有告诉我们足够的建议,所以请考虑一下。
答案 1 :(得分:0)
我的猜测是,您将受到低级文件访问代码,物理磁盘活动等的限制。多线程可能最终只会破坏磁盘。您对这些文件的位置有多少控制权并且在创建它们时会发生什么?
你能安排他们使用固态硬盘而不是物理磁盘吗?
您是否可以在数据到达时将数据加载到数据库中。那么您的搜索将跨越(可能是索引的)数据库?
答案 2 :(得分:0)
我会加载所有文件一次,保存为一个大文件。然后,您的应用程序只能加载一个文件并扫描300k文件,仅扫描那些已更改的文件(按大小,修改日期或删除/添加),将这些更改应用于内存中的大文件。
你说它们是小文件所以我假设一次可以加载300k文件 - 如果没有那么你必须只需要原始300k文件的子集,所以大文件可以只是那个子集。
这种方法不起作用的唯一方法是,每当你的应用程序运行时,其他东西都在写300k文件,这听起来不太可能。