调用IEnumerable.Count()需要几秒钟

Leg*_*nds 5 .net c#

我创建了一个小Windows服务,该服务应删除某些文件夹中所有出现的某个文件名。所有这些代码elapsed-handler都在计时器的时间间隔(intervall = 10s)中运行。

服务运行时,我可以识别出该服务使用的CPU最多增加20%,因此我检查了代码,在其中添加了一些跟踪命令,发现执行处理程序大约需要3-4秒。

我将其范围缩小为以下代码:allReporterFiles.Count()。它正在调用此方法Count()IEnumerable此调用需要3-4秒。

我的项目是为.NET 4.7.2设置的。这是框架错误还是什么?

 var files1 = Directory.EnumerateFiles(dirSwReporter, swReporterFileName, SearchOption.AllDirectories);
 var files2 = Directory.EnumerateFiles(dirSwReporter2, swReporterFileName, SearchOption.AllDirectories);

 var allReporterFiles = files1.Union(files2);

 var sw = Stopwatch.StartNew();
    var fileCount = allReporterFiles.Count(); // <--- takes ~3.5 seconds
 sw.Stop();

 Trace.WriteLine($"KillChromeSoftwareReporterTool completed in: {sw.Elapsed.TotalMilliseconds}ms or  {sw.Elapsed.TotalSeconds}sec");
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 12

这是框架错误还是什么?

我怀疑这是您对LINQ延迟执行的理解的问题。

allReporterFiles只是一个IEnumerable<string>。调用Count()意味着对其进行迭代-这又意味着Union代码将对files1and进行迭代files2。我怀疑您有很多文件。

告诉的方法是测量需要多长时间来遍历files1files2分开。一种简单的方法是致电ToList()。例如:

// The use of ToList forces the result to be materialized, rather than using deferred
// execution.

var stopwatch = Stopwatch.StartNew();
var files1 = Directory
    .EnumerateFiles(dirSwReporter, swReporterFileName, SearchOption.AllDirectories)
    .ToList();
var files1Time = stopwatch.Elapsed;

stopwatch.Restart();
var files2 = Directory
    .EnumerateFiles(dirSwReporter2, swReporterFileName, SearchOption.AllDirectories)
    .ToList();
var files2Time = stopwatch.Elapsed;
Run Code Online (Sandbox Code Playgroud)

然后登录files1Timefiles2Time。现在,内容在两个列表中,计算Union不涉及任何IO。HashSet<string>为了避免多次返回相同的值,它仍将需要基本上创建一个a ,但是它要快得多。

这种做法将不会有任何更快的整体-并且将使用更多的内存-但它会更明显地表是否大部分的时间是在寻找dirSwReporter或者dirSwReporter2,这可能足以您优化的帮助。