为什么EnumerateFiles比计算大小要快得多

MyD*_*ons 8 .net c#

对于我的WPF项目,我必须在单个目录(可能有子目录)中计算总文件大小.

样品1

DirectoryInfo di = new DirectoryInfo(path);
var totalLength = di.EnumerateFiles("*.*", SearchOption.AllDirectories).Sum(fi => fi.Length);

if (totalLength / 1000000 >= size)
    return true;
Run Code Online (Sandbox Code Playgroud)

样本2

 var sizeOfHtmlDirectory = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
 long totalLength = 0;
 foreach (var file in sizeOfHtmlDirectory)
 {
     totalLength += new FileInfo(file).Length;
     if (totalLength / 1000000 >= size)
         return true;
 }
Run Code Online (Sandbox Code Playgroud)

两个样本都有效.

样品1在更快的时间内完成.我没有准确计时,但在我的电脑上,使用相同内容/文件大小的相同文件夹,样本1需要几秒钟,样本2需要几分钟.

编辑

我应该指出,样品2中的瓶颈在foreach循环内!它快速读取GetFiles并快速进入foreach循环.

我的问题是,我怎么知道为什么会这样呢?

Bro*_*ass 8

与其他答案所表明的相反,主要区别不是EnumerateFilesvs GetFiles- 它是DirectoryInfovs Directory- 在后一种情况下,你只有字符串并且必须分别创建新的FileInfo实例,这是非常昂贵的.

DirectoryInfo返回FileInfo使用缓存信息的FileInfo实例,而不是直接创建没有的新实例 - 这里这里有更多细节.

相关报价(通过"旧的新事物"):

在NTFS中,文件系统元数据不是目录条目的属性,而是文件的属性,其中一些元数据作为调整复制到目录条目中以提高目录枚举性能.像FindFirstFile这样的函数报告目录条目,并且通过放置FAT用户习惯于"免​​费"获取的元数据,它们可以避免比目录列表的FAT慢.directory-enumeration函数报告上次更新的元数据,如果目录条目是陈旧的,则可能与实际元数据不对应.