gpt4 book ai didi

c# - .NET 4.0 并发收集性能

转载 作者:可可西里 更新时间:2023-11-01 08:28:10 26 4
gpt4 key购买 nike

我正在尝试编写一个程序,在该程序中,我通过将项目放入来自不同线程的集合中并在迭代集合并处理项目的单个线程中清理它们来安排要删除的项目。

在这样做之前,我想知道什么会产生最佳性能,所以我尝试了 ConcurrentBag、ConcurrentStack 和 ConcurrentQueue 并测量了添加 10000000 个项目所需的时间。

我用下面的程序来测试这个:

class Program
{
static List<int> list = new List<int>();
static ConcurrentBag<int> bag = new ConcurrentBag<int>();
static ConcurrentStack<int> stack = new ConcurrentStack<int>();
static ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
static void Main(string[] args)
{
run(addList);
run(addBag);
run(addStack);
run(addQueue);
Console.ReadLine();
}

private static void addList(int obj) { lock (list) { list.Add(obj); } }

private static void addStack(int obj) { stack.Push(obj); }

private static void addQueue(int obj) { queue.Enqueue(obj); }

private static void addBag(int obj) { bag.Add(obj); }



private static void run(Action<int> action)
{
Stopwatch stopwatch = Stopwatch.StartNew();
Parallel.For(0, 10000000, new ParallelOptions() { MaxDegreeOfParallelism = # }, action);
stopwatch.Stop();
Console.WriteLine(action.Method.Name + " takes " + stopwatch.Elapsed);
}
}

其中 # 是使用的线程数。

但结果相当困惑:

有 8 个线程:

  • addList 取 00:00:00.8166816
  • addBag 需要 00:00:01.0368712
  • addStack 占用 00:00:01.0902852
  • addQueue 需要 00:00:00.6555039

有 1 个线程:

  • addList 取 00:00:00.3880958
  • addBag 需要 00:00:01.5850249
  • addStack 需要 00:00:01.2764924
  • addQueue 占用 00:00:00.4409501

因此,无论有多少线程,似乎只锁定一个普通的旧列表比使用任何并发集合更快,除非,如果它需要处理大量写入,则可能是队列。

编辑:在下面关于垃圾和调试构建的评论之后:是的,这会影响基准。调试构建影响将是线性的,垃圾将随着内存使用量的增加而增加。

但多次运行相同的测试会得到大致相同的结果。

我将收集的初始化移动到测试运行之前,现在运行后收集垃圾,如下所示:

        list = new List<int>();
run(addList);
list = null;
GC.Collect();

将 MaxDegreeOfParallelism 设置为 8 我得到以下结果:

  • addList 需要 00:00:7959546
  • addBag 需要 00:00:01.08023823
  • addStack 需要 00:00:01.1354566
  • addQueue 需要 00:00:00.6597145

每次运行代码时都会有 0.02 秒的偏差。

最佳答案

并发收集并​​不总是更快。他们中的更多人只会在更高级别的争用中看到性能提升,并且实际工作负载也会产生影响。查看 pfx 团队的这篇论文 :)

http://blogs.msdn.com/b/pfxteam/archive/2010/04/26/9997562.aspx

不过要提防过早的优化。将有效的东西放在一起,然后进行优化。特别是因为实际工作量很重要。此外,将锁作为 perf 瓶颈是非常重要的,通常有一些 io 或其他算法需要更长的时间:)

关于c# - .NET 4.0 并发收集性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19326197/

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