加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 06:25:33 所属栏目:百科 来源:网络整理
导读:我正在尝试编写一个程序,我将通过将其从不同的线程放在一个集合中并将其清理到一个单独的线程中来迭代集合并处理这些项目,从而将其删除. 在这样做之前,我想知道什么会产生最佳性能,所以我尝试了ConcurrentBag,ConcurrentStack和ConcurrentQueue,并测量了添加
我正在尝试编写一个程序,我将通过将其从不同的线程放在一个集合中并将其清理到一个单独的线程中来迭代集合并处理这些项目,从而将其删除.

在这样做之前,我想知道什么会产生最佳性能,所以我尝试了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或其他算法需要更长的时间:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读