我已经创建了一个小窗口服务,它应该删除某些文件夹中某个文件名的所有出现。所有这些代码都运行在计时器的elapsed-handler (intervall=10s)中。
当服务运行时,我可以识别出该服务使用的CPU增加了20%,所以我检查了我的代码,在其中放置了一些跟踪命令,发现执行处理程序花费了大约3-4秒的时间。
我将其缩小到以下代码段:allReporterFiles.Count()。它调用这个IEnumerable的方法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");发布于 2019-10-02 20:56:06
这是框架错误还是什么?
这是一个问题,你理解LINQ的延迟执行,我怀疑。
allReporterFiles只是一个IEnumerable<string>。调用Count()意味着迭代它-这反过来意味着Union代码在files1和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;然后记录files1Time和files2Time。现在,内容在两个列表中,计数Union将不涉及任何IO。为了避免不止一次地返回相同的值,它仍然需要按原样创建一个HashSet<string>,但是它会更快,更快。
这种方法在总体上不会更快--而且会使用更多内存--但它会让人清楚地知道,大多数时间是在dirSwReporter还是dirSwReporter2中搜索,这可能足以帮助您进行优化。
发布于 2019-10-02 22:26:36
关于延迟执行的信息隐藏在.NET Framework4.7Directory.EnumerateFiles法的doco的备注部分中。
EnumerateFiles和GetFiles方法的不同之处如下:使用EnumerateFiles时,可以在返回整个集合之前开始枚举名称集合;使用GetFiles时,必须等待返回整个名称数组后才能访问该数组。因此,当您处理许多文件和目录时,EnumerateFiles可以更高效。
关于效率的部分显然与上下文无关,因为您正在对结果调用Count,这需要完整的枚举。
顺便说一下。.NET Framework4.8Directory.EnumerateFiles法的doco声明:
返回的集合不被缓存;每次对集合上的GetEnumerator调用都将启动一个新的枚举。
https://stackoverflow.com/questions/58209175
复制相似问题