gpt4 book ai didi

c# - 在 Parallel for 中使用 ConcurrentBag 与简单数组

转载 作者:太空宇宙 更新时间:2023-11-03 11:04:52 24 4
gpt4 key购买 nike

这是一个假设性问题/用例,它基于(在本例中)针对此特定用例在 Parallel for 循环中对简单数组使用 ConcurrentBag 的好处。

该场景基于使用通用管道模式来分析从 1 到 总计 结果的数字,根据管道操作之一的输出存储结果为空。

结果列表的实际顺序很重要,因此使用一个简单的列表(字符串类型).add 会导致奇怪,这取决于每个线程决定返回结果的时间。

我有以下工作代码:

    public IList<string> Execute(int total)
{
var items = new ConcurrentBag<AnalyzerResult>();

Parallel.ForEach(Iterate(1, (total + 1)), d =>
{
foreach (IOperation<T> operation in operations)
{
var result = operation.Execute(d);
if (result != null)
{
items.Add(new AnalyzerResult(d, result));
break;
}
}
});

return items.OrderBy(o=>o.SortOrder).Select(d => d.Result).ToList();
}

AnalyzerResult 是一个简单的不可变类,代码只会将新项目推送到包中(因此从理论上讲,items 列表中的内容不会有被更改的危险)。

基于此,一个简单的数组就足够了吗(并且包含更少的代码噪音)?还是使用并发类型被认为是更好的实践/更高的性能?例如:

    public IList<string> Execute(int total)
{
var items = new string[total];

Parallel.ForEach(Iterate(1, (total + 1)), d =>
{
foreach (IOperation<T> operation in operations)
{
var result = operation.Execute(d);
if (result != null)
{
items[(d - 1)] = result;
break;
}
}
});

return items.ToList();
}

注意:这不是并发问题,这两种方法都是合法的并且可以毫无问题地产生预期的结果。

最佳答案

我最初的回答是“你需要并发保护”,但后来又重读了你问题的第二部分。

这看起来应该可行,因为您不会尝试从两个不同的线程写入内存中的相同位置。因此,消除锁和线程关联(ConcurrentBag 提供)应该会显着提高性能。

真正的问题是 - 增加了多少,是否需要增加(需要剖析),以及您将来是否会更改此设置以便需要并发保护。

照原样,它应该没问题,而且可读性很强。您可能想要评论这段代码,说明您为什么这样做,以确保有人不会随意浏览它并认为“并发问题”(就像我刚才所做的那样)并“修复”它。

关于c# - 在 Parallel for 中使用 ConcurrentBag 与简单数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16264445/

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