Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Paralell.Foreach()时Diretory.GetFiles()的性能_C#_Performance_Getfiles - Fatal编程技术网

C# 使用Paralell.Foreach()时Diretory.GetFiles()的性能

C# 使用Paralell.Foreach()时Diretory.GetFiles()的性能,c#,performance,getfiles,C#,Performance,Getfiles,众所周知,Directory.GetFiles()不是很快。 我想尽快找到一些文件。 我遇到了一些奇怪的结果 我开始使用Parallel.ForEach并在我的C:\-Drive上迭代所有directory 我实现了3种方法并显示了结果。它们在我过去在目录中深入研究的并行数上有所不同 这是结果 我不明白为什么使用一个并行比使用两个并行更快。。。 我一点也不明白为什么他们发现的文件数量不同 长话短说以下是我的代码: 来电者 private void Start(对象发送方,事件参数e) { 新线

众所周知,Directory.GetFiles()不是很快。 我想尽快找到一些文件。 我遇到了一些奇怪的结果

我开始使用
Parallel.ForEach
并在我的
C:\-Drive
上迭代所有
directory

我实现了3种方法并显示了结果。它们在我过去在目录中深入研究的并行数上有所不同

这是结果

我不明白为什么使用一个并行比使用两个并行更快。。。 我一点也不明白为什么他们发现的文件数量不同

长话短说以下是我的代码:

来电者

private void Start(对象发送方,事件参数e)
{
新线程(()=>
{
秒表=新秒表();
watch.Start();
List files=highperformancefilegetter.GetFilesInDirectory\u DoubleParallel(@“C:\”、“*.txt”、SearchOption.AllDirectories);
看,停;
MessageBox.Show($“在[{watch.appeased.totalms}ms]中找到[{files.Count}]文件=>[{watch.appeased.TotalSeconds}]s”,“双并行”);
}).Start();
新线程(()=>
{
秒表=新秒表();
watch.Start();
List files=highperformancefilegetter.GetFilesInDirectory\u SingleParallell(@“C:\”、“*.txt”、SearchOption.AllDirectories);
看,停;
MessageBox.Show($“在[{watch.appeased.totalmillizes}ms]=>[{watch.appeased.TotalSeconds}]s中找到[{files.Count}]个文件”,“单并行”);
}).Start();
新线程(()=>
{
秒表=新秒表();
watch.Start();
List files=highperformancefilegetter.GetFilesInDirectory\u TripleParallel(@“C:\”、“*.txt”、SearchOption.AllDirectories);
看,停;
MessageBox.Show($“在[{watch.appeased.totalms}ms]中找到[{files.Count}]文件=>[{watch.appeased.TotalSeconds}]s”,“Tripe Parallel”);
}).Start();
}
搜索:

publicstaticlist GetFilesInDirectory\u TripleParallel(stringrootdirectory、stringpattern、System.IO.SearchOption选项)
{
列表结果文件=新列表();
//苏晨:
DirectoryInfo root=新的DirectoryInfo(rootDirectory);
if(root.Exists)
{
//性能:
Parallel.ForEach(root.GetDirectories(),(dir)=>
{
尝试
{
Parallel.ForEach(dir.GetDirectories(),(dir_1)=>
{
尝试
{
Parallel.ForEach(dir_1.GetDirectories(),(dir_2)=>
{
尝试
{
AddRange(dir_2.GetFiles(pattern,option));
}
捕获(异常){}
}); 
}
捕获(异常){}
});
}
捕获(异常){}
});
返回结果文件;
}
Debug.Fail($“根[{Root.FullName}]不存在”);
返回null;
}
注意:我刚刚发布了三种方法中的一种,但你可以看到有什么不同。这只是我用的平行数


有人知道在性能方面最好的术语是什么,以及为什么文件计数不同吗?

不同文件计数的原因是
SearchOption.AllDirectories
。在单并行版本中,如果阅读
C:\
,则会得到所有子目录中的所有文件。在你的三重版本中

  • 下面所有子目录中的所有文件
    C:
    `
  • 加上`C:\dir1´(->重复项)下所有子目录中的所有文件
  • 加上下面所有子目录中的所有文件
    C:\dir1\dir2
    (->新副本)
因此,
C:\
中的所有文件添加一次,
C:\dir1
中的所有文件添加两次,
C:\dir1\dir2
中的所有文件添加三次

对于测量的时间:如果从单个硬盘驱动器读取,并行化将没有帮助。这里导致延迟的是I/O系统。即使是一百个线程也要等待硬盘。因此,我实际上希望并行化会因为开销而降低整个操作的速度


有趣的是,三重版本速度最快,尽管它读取目录的频率更高,但这可能是由文件系统的缓存造成的。因此,如果您在一个进程中一个接一个地直接运行所有三个测试,那么您的测试实际上并不正确。

不同文件计数的原因是
SearchOption.AllDirectories
。在单并行版本中,如果阅读
C:\
,则会得到所有子目录中的所有文件。在你的三重版本中

  • 下面所有子目录中的所有文件
    C:
    `
  • 加上`C:\dir1´(->重复项)下所有子目录中的所有文件
  • 加上下面所有子目录中的所有文件
    C:\dir1\dir2
    (->新副本)
因此,
C:\
中的所有文件添加一次,
C:\dir1
中的所有文件添加两次,
C:\dir1\dir2
中的所有文件添加三次

对于测量的时间:如果从单个硬盘驱动器读取,并行化将没有帮助。这里导致延迟的是I/O系统。即使是一百个线程也要等待硬盘。因此,我实际上希望并行化会因为开销而降低整个操作的速度

有趣的是,三重版本是最快的
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;
    }