【发布时间】:2016-08-30 19:59:44
【问题描述】:
众所周知,Directory.GetFiles() 不是很快。 我试图尽快找到一些文件。 我遇到了一些奇怪的结果。
我开始使用Parallel.ForEach 并在我的C:\-Drive 上迭代所有Directorys。
我实现了 3 个方法并显示了结果。它们在我用来深入目录的 Parallels 数量上有所不同。
这是结果。
我不明白为什么使用单个 Parallel 比使用两个更快... 我根本不明白为什么他们找到的文件数量不同?!
长话短说,这是我的代码:
来电者
private void Start(object sender, EventArgs e)
{
new Thread(() =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
List<FileInfo> files = HighPerformanceFileGettter.GetFilesInDirectory_DoubleParallel(@"C:\", "*.txt", SearchOption.AllDirectories);
watch.Stop();
MessageBox.Show($"Found [{files.Count}] files in [{watch.Elapsed.TotalMilliseconds}ms] => [{watch.Elapsed.TotalSeconds}]s", "Double Parallel");
}).Start();
new Thread(() =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
List<FileInfo> files = HighPerformanceFileGettter.GetFilesInDirectory_SingleParallell(@"C:\", "*.txt", SearchOption.AllDirectories);
watch.Stop();
MessageBox.Show($"Found [{files.Count}] files in [{watch.Elapsed.TotalMilliseconds}ms] => [{watch.Elapsed.TotalSeconds}]s", "Single Parallel");
}).Start();
new Thread(() =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
List<FileInfo> files = HighPerformanceFileGettter.GetFilesInDirectory_TripleParallel(@"C:\", "*.txt", SearchOption.AllDirectories);
watch.Stop();
MessageBox.Show($"Found [{files.Count}] files in [{watch.Elapsed.TotalMilliseconds}ms] => [{watch.Elapsed.TotalSeconds}]s", "Tripe Parallel");
}).Start();
}
搜索:
public static List<FileInfo> GetFilesInDirectory_TripleParallel(string rootDirectory, string pattern, System.IO.SearchOption option)
{
List<FileInfo> resultFiles = new List<FileInfo>();
//Suchen:
DirectoryInfo root = new DirectoryInfo(rootDirectory);
if (root.Exists)
{
//Performance:
Parallel.ForEach(root.GetDirectories(), (dir) =>
{
try
{
Parallel.ForEach(dir.GetDirectories(), (dir_1) =>
{
try
{
Parallel.ForEach(dir_1.GetDirectories(), (dir_2) =>
{
try
{
resultFiles.AddRange(dir_2.GetFiles(pattern, option));
}
catch (Exception) { }
});
}
catch (Exception) { }
});
}
catch (Exception) { }
});
return resultFiles;
}
Debug.Fail($"Root [{root.FullName}] does not exist");
return null;
}
注意:我刚刚发布了三种方法中的一种,但你大喊看看有什么不同。它只是我使用的 Paralell.Foreach'es 的计数。
有没有人知道在性能方面最好的术语是什么以及为什么文件数不同?
【问题讨论】:
-
如果您可以在返回结果时一次使用一个结果,那么Directory.EnumerateFiles 可能会有所帮助。至于不同的文件数,你检查过重复吗?
-
就速度而言,磁盘 I/O 是主要的限制因素。您可以拥有任意数量的并行进程,但磁盘的寻道速度只能如此之快。
-
@AndrewMorton 即使有重复,不是所有三个函数都应该找到它们吗?
-
List不是线程安全的。这应该是导致不同结果的原因。尝试使用线程安全集合。 -
使用线程从磁盘驱动器读取是一个非常非常糟糕的主意。您只有一个驱动器,它确实不喜欢让多个线程满意。磁盘寻道是迄今为止使用驱动器所能做的最昂贵的事情。特别危险,因为它不能很好地重复,第二次运行程序时,您将从内存而不是磁盘读取。警示故事是available here。
标签: c# performance getfiles