gpt4 book ai didi

c# - for循环进入0% cpu hang

转载 作者:太空宇宙 更新时间:2023-11-03 16:01:20 25 4
gpt4 key购买 nike

我需要获取一个文件列表,将它们修剪到目录路径并返回一个不同的列表。在某些情况下,这可能会处理超过 500 万个文件。

我遇到了一个问题,即核心进程因 CPU 使用率 0% 而挂起,原因我无法确定。

var filePaths = File.ReadAllLines("list_of_files.txt");
// ...
blockSw.Restart();
int[] curCounter = new int[1];
Stopwatch groupSw = Stopwatch.StartNew();
Parallel.For(0, filePaths.LongLength, i =>
{
//Trim the filename, if it exists, off of every
// entry that we read out of the input file
filePaths[i] = (Path.GetDirectoryName(filePaths[i]));
//This can be used to safely report status
// little hack-y, though
lock (curCounter)
{
curCounter[0]++;
if (curCounter[0] % 100000 == 0)
{
Trace.WriteLine(curCounter[0].ToString() + " rows complete in "
+ groupSw.ElapsedMilliseconds
+ " ; total time: " + blockSw.ElapsedMilliseconds);
groupSw.Restart();
}
}
}
);
blockSw.Stop();
Trace.WriteLine("Completed path truncation in " + blockSw.ElapsedMilliseconds + "ms.");

然后输出看起来像这样:

100000 rows complete in 266 ; total time: 266
200000 rows complete in 239 ; total time: 507
300000 rows complete in 843 ; total time: 1351
400000 rows complete in 1058 ; total time: 2411
...
1100000 rows complete in 3480 ; total time: 11602
1200000 rows complete in 432 ; total time: 12036
1300000 rows complete in 342 ; total time: 12379
...
4800000 rows complete in 832 ; total time: 48617
4900000 rows complete in 377 ; total time: 48996
5000000 rows complete in 2841 ; total time: 51839
5100000 rows complete in 1285 ; total time: 53126
Completed path truncation in 148124ms.

注意最后两行... 53 秒完成所有操作,然后循环结束,我们坐下来等待约 90 秒。观察 TaskManager 中的进程,我可以看到它在此期间仅以 0% 的 CPU 闲置。

关于这里发生了什么或我可以在哪里寻找线索的任何线索?

列出文件路径的输入文件约为 400MB,在此过程中 TaskManager 报告的内存大小约为 900MB。在测试期间,有大量可用物理 RAM 高于此数量。

移除循环内状态报告不会对性能产生任何影响 - 在循环结束时,我们仍然会遇到约 90 秒的 0% CPU 使用率挂起。

我对标准 for 循环而不是 Parallel.For 有同样的问题。


更新/解决方案

感谢克里斯、 jack 和汉斯。有了 Chris 无法重现的输入和 Hans 对 Break All 的建议,我能够缩小问题的范围。进一步调试,我发现实际问题是 Path.GetDirectoryName 是罪魁祸首。虽然它在几乎每个文件路径上都以 0-15 毫秒的速度运行,但有几十个路径需要长达 2 分钟的时间来处理。我注意到这些路径中都包含 ~ 。我仍然不清楚为什么它在根本不使用 CPU 的情况下执行此操作,但足以让我理解它是 Path 内部的并且加速它的唯一方法是重新实现 GetDirectoryName.

最佳答案

至于distinct.
可能不会比全部执行然后执行单个 LINQ 更快,但它应该占用更少的内存。

using (StreamReader sr = new StreamReader("TestFile.txt"))
{
String line;
String path;
HashSet<string> paths = HashSet<string>(StringComparer.OrdinalIgnoreCase);
// Read and process lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
path = Path.GetDirectoryName(line);
if(!String.IsNullOrEmpty(path)) paths.Add(path.Trim());
}
}

关于c# - for循环进入0% cpu hang,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21207903/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com