C#:AsParallel - 订单有关系吗?

Ste*_*fen 15 plinq c#-4.0

我正在构建一个简单的LinQ-to-object查询,我想并行化,但是我想知道语句的顺序是否重要?

例如

IList<RepeaterItem> items;

var result = items
        .Select(item => item.FindControl("somecontrol"))
        .Where(ctrl => SomeCheck(ctrl))
        .AsParallel();
Run Code Online (Sandbox Code Playgroud)

var result = items
        .AsParallel()
        .Select(item => item.FindControl("somecontrol"))
        .Where(ctrl => SomeCheck(ctrl));
Run Code Online (Sandbox Code Playgroud)

会有什么不同吗?

Jon*_*eet 23

绝对.在第一种情况下,投影和过滤将按顺序进行,然后才会进行任何并行化.

在第二种情况下,投影和滤波都将并行发生.

除非你有特殊的理由使用第一个版本(例如投影具有线程亲和力,或其他一些奇怪的东西),你应该使用第二个版本.

编辑:这是一些测试代码.有许多基准测试有缺陷,但结果是合理的结论:

using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;

class Test
{
    static void Main()
    {
        var query = Enumerable.Range(0, 1000)
                              .Select(SlowProjection)
                              .Where(x => x > 10)
                              .AsParallel();
        Stopwatch sw = Stopwatch.StartNew();
        int count = query.Count();
        sw.Stop();
        Console.WriteLine("Count: {0} in {1}ms", count,
                          sw.ElapsedMilliseconds);

        query = Enumerable.Range(0, 1000)
                          .AsParallel()
                          .Select(SlowProjection)
                          .Where(x => x > 10);
        sw = Stopwatch.StartNew();
        count = query.Count();
        sw.Stop();
        Console.WriteLine("Count: {0} in {1}ms", count,
                          sw.ElapsedMilliseconds);
    }

    static int SlowProjection(int input)
    {
        Thread.Sleep(100);
        return input;
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

Count: 989 in 100183ms
Count: 989 in 13626ms
Run Code Online (Sandbox Code Playgroud)

现在PFX中有许多启发式的东西,但很明显第一个结果根本没有并行化,而第二个结果没有.