Directory.GetFiles() 性能问题

Directory.GetFiles() performance issues

使用 System.IO.Directory.GetFiles(),我想找到位于 NAS 服务器上的图像 .png 扩展。

string searchingString = "ZLLK9";
// original
var fileList1= Directory.GetFiles(directoryPath).Select(p => new FileInfo(p)).Where(q => q.Name.Substring(0, q.Name.LastIndexOf('.')).Split('_').First() == searchingString);
// fixed    
var fileList2 = Directory.GetFiles(directoryPath, string.Format("{0}_*.png", searchingString));

有两种方法可以找出包含 "ZLLKK9" 个单词的文件。

第一种 'original' 使用 LINQ 的方法太慢,无法找到文件。 性能问题出现了,但我不知道 'fixed' 方式有什么不同?

我需要帮助才能仔细理解两种方式的区别。

第一个是获取该目录中的所有文件对象,然后进行查询以查找名称。

第二个是仅使用 windows 内部 API 名称的 return 文件,这比 c# 方法 ( LINQ ) 快得多。

性能上的差异更多地利用了比 C# 代码更快的内部 API。

第一种方法很慢,原因有二:

  • 您正在为每个文件构造一个 FileInfo 对象。如果您只需要文件名,则不需要这样做。构建 FileInfo 相对较轻,但没有必要,如果您查询大量文件,所有实例化都会减慢您的速度。由于您真正需要的只是文件名,因此您可以省去这个额外的步骤。

  • LINQ 方法检索所有内容,然后进行过滤。让文件系统为您进行过滤会更有效率(也更快)。

如果您仍想使用 LINQ,这里有一个性能更高的查询版本,它省去了很多枚举和字符串操作:

var fileList1 = Directory.GetFiles(directoryPath).Where(
    path => Regex.IsMatch(Path.GetFileName(path), @"^ZLLK9_.*\.png$"));

答案在于你使用的方式GetFiles()

您的原始解决方案从目录中获取所有文件。然后,您的软件会遍历它们以找到正确的模式。此处的文档:Directory.GetFiles Method (String).

您的固定版本使用了不同的 .NET Framework 方法,即 Directory.GetFiles Method (String, String)。第二个参数是搜索模式。在这里过滤文件不是通过您自己编写的代码 (LINQ),而是通过底层操作系统本身。