gpt4 book ai didi

c# - ConcurrentBag 与自定义线程安全列表

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

我有一个 .NET 4.5 单实例 WCF 服务,它维护列表中的项目集合,该列表将同时具有并发的读者和作者,但读者比作者多得多。

我目前正在决定是否使用 BCL ConcurrentBag<T>或使用我自己的自定义通用 ThreadSafeList类(它扩展了 IList<T> 并封装了 BCL ReaderWriterLockSlim,因为这更适合多个并发读取器)。

通过模拟 100 万读者(简单地运行 Sum Linq 查询)和只有 100 位作者(向列表添加项目)的并发场景来测试这些实现时,我发现了许多性能差异。

对于我的性能测试,我有一个任务列表:

List<Task> tasks = new List<Task>();

测试 1:如果我使用以下代码创建 100 万个读取器任务和 100 个写入器任务:

tasks.AddRange(Enumerable.Range(0, 1000000).Select(n => new Task(() => { temp.Where(t => t < 1000).Sum(); })).ToArray());
tasks.AddRange(Enumerable.Range(0, 100).Select(n => new Task(() => { temp.Add(n); })).ToArray());

我得到以下计时结果:

  • 并发包:~300 毫秒
  • 线程安全列表:~520ms

测试 2:但是,如果我创建 100 万个读取器任务和 100 个写入器任务(因此要执行的任务列表可以是 {Reader,Reader,Writer,Reader,Reader,Writer etc}

foreach (var item in Enumerable.Range(0, 1000000))
{
tasks.Add(new Task(() => temp.Where(t => t < 1000).Sum()));
if (item % 10000 == 0)
tasks.Add(new Task(() => temp.Add(item)));
}

我得到以下计时结果:

  • 并发包:~4000ms
  • 线程安全列表:~800 毫秒

我获取每个测试执行时间的代码如下:

Stopwatch watch = new Stopwatch();
watch.Start();
tasks.ForEach(task => task.Start());
Task.WaitAll(tasks.ToArray());
watch.Stop();
Console.WriteLine("Time: {0}ms", watch.Elapsed.TotalMilliseconds);

ConcurrentBag 在测试 1 中的效率更好,ConcurrentBag 在测试 2 中的效率比我的自定义实现差,因此我发现很难决定使用哪个。

Q1。当我唯一要更改的是列表中任务的排序时,为什么结果会如此不同?

Q2。有没有更好的方法来更改我的测试以使其更公平?

最佳答案

Why are the results so different when the only thing I’m changing is the ordering of the tasks within the list?

我最好的猜测是 Test #1 实际上没有阅读 项目,因为没有什么可读的。任务执行顺序为:

  1. 从共享池中读取1M次并计算总和
  2. 写入共享池 100 次

您的测试 #2 混合了读取和写入,我猜这就是为什么您会得到不同结果的原因。

Is there a better way to change my test to make it more fair?

在开始任务之前,尝试随机化任务的顺序。可能很难重现相同的结果,但您可能会更接近真实世界的使用情况。

最终,您的问题是关于乐观并发(Concurrent* 类)与悲观并发(基于锁)的区别。根据经验,当您同时访问共享资源的机会很低时,更喜欢乐观并发。当同时访问的机会很高时,更喜欢悲观的。

关于c# - ConcurrentBag 与自定义线程安全列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30531122/

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