我创建了一个小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。我怀疑您有很多文件。
告诉的方法是测量需要多长时间来遍历files1和files2分开。一种简单的方法是致电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)
然后登录files1Time并files2Time。现在,内容在两个列表中,计算Union不涉及任何IO。HashSet<string>为了避免多次返回相同的值,它仍将需要基本上创建一个a ,但是它要快得多。
这种做法将不会有任何更快的整体-并且将使用更多的内存-但它会更明显地表是否大部分的时间是在寻找dirSwReporter或者dirSwReporter2,这可能足以您优化的帮助。
| 归档时间: |
|
| 查看次数: |
341 次 |
| 最近记录: |