PLINQ 的性能比通常的 LINQ 差 [英] PLINQ Performs Worse Than Usual LINQ

查看:16
本文介绍了PLINQ 的性能比通常的 LINQ 差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

令人惊讶的是,在我创建的一个小测试用例中,使用 PLINQ 并没有产生任何好处;事实上,它甚至比通常的 LINQ 还要糟糕.

Amazingly, using PLINQ did not yield benefits on a small test case I created; in fact, it was even worse than usual LINQ.

测试代码如下:

    int repeatedCount = 10000000;
    private void button1_Click(object sender, EventArgs e)
    {
        var currTime = DateTime.Now;
        var strList = Enumerable.Repeat(10, repeatedCount);
        var result = strList.AsParallel().Sum();

        var currTime2 = DateTime.Now;
        textBox1.Text = (currTime2.Ticks-currTime.Ticks).ToString();

    }

    private void button2_Click(object sender, EventArgs e)
    {
        var currTime = DateTime.Now;
        var strList = Enumerable.Repeat(10, repeatedCount);
        var result = strList.Sum();

        var currTime2 = DateTime.Now;
        textBox2.Text = (currTime2.Ticks - currTime.Ticks).ToString();
    }

结果?

textbox1: 3437500
textbox2: 781250

所以,LINQ 比 PLINQ 花费更少的时间来完成类似的操作!

So, LINQ is taking less time than PLINQ to complete a similar operation!

我做错了什么?或者有什么我不知道的转折?

What am I doing wrong? Or is there a twist that I don't know about?

我已经更新了我的代码以使用秒表,但同样的行为仍然存在.为了降低 JIT 的影响,我实际上尝试了几次同时单击 button1button2 并且没有特定的顺序.虽然我得到的时间可能不同,但定性行为仍然存在:在这种情况下,PLINQ 确实更慢了.

I've updated my code to use stopwatch, and yet, the same behavior persisted. To discount the effect of JIT, I actually tried a few times with clicking both button1 and button2 and in no particular order. Although the time I got might be different, but the qualitative behavior remained: PLINQ was indeed slower in this case.

推荐答案

第一: 停止使用 DateTime 来测量运行时间.改用秒表.测试代码如下所示:

First: Stop using DateTime to measure run time. Use a Stopwatch instead. The test code would look like:

var watch = new Stopwatch();

var strList = Enumerable.Repeat(10, 10000000);

watch.Start();
var result = strList.Sum();
watch.Stop();

Console.WriteLine("Linear: {0}", watch.ElapsedMilliseconds);

watch.Reset();

watch.Start();
var parallelResult = strList.AsParallel().Sum();
watch.Stop();

Console.WriteLine("Parallel: {0}", watch.ElapsedMilliseconds);

Console.ReadKey();

第二:并行运行会增加开销.在这种情况下,PLINQ 必须找出划分集合的最佳方法,以便它可以安全地并行对元素求和.之后,您需要将创建的各个线程的结果连接起来,并对它们求和.这不是一项微不足道的任务.

Second: Running things in Parallel adds overhead. In this case, PLINQ has to figure out the best way to divide your collection so that it can Sum the elements safely in parallel. After that, you need to join the results from the various threads created and Sum those as well. This isn't a trivial task.

使用上面的代码,我可以看到使用 Sum() 可以实现约 95 毫秒的调用.在大约 185 毫秒左右调用 .AsParallel().Sum() 网络.

Using the code above I can see that using Sum() nets a ~95ms call. Calling .AsParallel().Sum() nets around ~185ms.

并行执行一项任务只有在您通过这样做有所收获时才是一个好主意.在这种情况下,Sum 是一项足够简单的任务,您无法通过使用 PLINQ 获得.

Doing a task in Parallel is only a good idea if you gain something by doing it. In this case, Sum is a simple enough task that you don't gain by using PLINQ.

这篇关于PLINQ 的性能比通常的 LINQ 差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆