背景:我有一个流程,可以从数据集中构建一些用户定义的报告行。主数据集包含List<Foo>
中的大约400k项。然后该列表中的每个项目都包含 n 子项。然后,每个孩子在 i 次上进行迭代,以构建List<string>
,最终将其添加到ConcurrentQueue<List<string>>
。所以整个过程看起来像这样
var concurrentQueue = new ConcurrentQueue<List<string>>();
var parentList = new List<Foo>();
//...seed parentList
Parallel.ForEach(parentList, row =>
{
//...determine how many children exist for row
for (var i = 0; i <= numberOfChildren; i++)
{
var row = new List<string>();
for (var i = 0; i <= numberOfColumns; i++)
{
//...add an item to row
}
concurrentQueue.Enqueue(row);
}
});
我有一些日志记录可以报告添加到ConcurrentQueue
的每5k行。我注意到随着时间的推移,添加行的时间逐渐增加。所以前100k的父行可能每5k需要7分钟,但是一旦我们超过300k就会花费两倍的时间。子女的数量虽然不是静态的,但从父母到父母的偏差并不大。
有没有人对为什么会出现性能降级有假设?代码中的任何瓶颈都应该从一开始就显而易见,我预计资源瓶颈会导致逐渐减速,尽管似乎也不是这样(我已经验证了CPU使用率和内存使用率不是一个问题)。 Parallel.ForEach
也将ParallelOptions.MaxDegreesOfParallelism
设置为10,因此也不会发生线程爆炸。