代码之家  ›  专栏  ›  技术社区  ›  pablo

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

  •  1
  • pablo  · 技术社区  · 14 年前

    我需要找到一种方法来尽快读取大量的小文件(大约300k个文件)。

    使用filestream按顺序读取它们,并在一次调用中读取整个文件需要170到208秒(要知道,重新运行时,磁盘缓存扮演着它的角色,时间也不尽相同)。

    然后我尝试将pinvoke与createfile/readfile一起使用,并使用file_flag_sequential_scan,但我不喜欢任何更改。

    我尝试了几个线程(将大的集合分成块,让每个线程都读取它的部分),这样我就可以稍微提高速度(甚至不是5%,每个新线程高达4)。

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

    3 回复  |  直到 14 年前
        1
  •  1
  •   High Performance Mark    14 年前

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

    您可以考虑的一个选项是迁移到为多线程访问而设计的并行I/O系统。不过,这是一个很大的步骤,只有在您定期进行此类操作时才适用。

    另一个选择是在网络系统上的本地磁盘上分发文件,并让每个系统通过一部分文件工作。对你来说,实现这一点是多么容易,但是你没有告诉我们足够多的信息,我们无法就此给出很好的建议,所以好好想想吧。

        2
  •  0
  •   djna    14 年前

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

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

    你能在数据到达时把它装入数据库吗?那么您的搜索将跨越(可能是索引的)数据库?

        3
  •  0
  •   Enigmativity    14 年前

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

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

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