简体   繁体   English

AsParallel - Linq之前和之后的条款表现

[英]AsParallel - Before vs After in Linq Where Clause Performance

I'm having a List<Boss> Collection, every Boss has 2 to 10 Assistant Staff. 我有一个List<Boss> Collection,每个Boss都有2到10名助理员工。 I'm grouping all the Employees including Boss. 我正在将包括Boss在内的所有员工分组。 Now I'm having List<Person> , from this I'm searching "Raj" using Parallel LINQ , where can I place the supportive method AsParallel() to get better performance, Before or After the Where Clause ? 现在我有List<Person> ,从这里我使用Parallel LINQ搜索“Raj” ,在哪里可以放置支持方法AsParallel()以获得更好的性能,在Where子句之前或之后?

public class Person
{
    public int EmpID { get; set; }
    public string Name { get; set; }
    public string Department { get; set; }
    public string Gender { get; set; }
}

void Main()
{

    List<Boss> BossList = new List<Boss>()
    {
        new Boss()
        {
            EmpID = 101,
            Name = "Harry",
            Department = "Development",
            Gender = "Male",
            Employees = new List<Person>()
            {
                new Person() {EmpID = 102, Name = "Peter", Department = "Development",Gender = "Male"},
                new Person() {EmpID = 103, Name = "Emma Watson", Department = "Development",Gender = "Female"},

            }
        },
        new Boss()
        {
            EmpID = 104,
            Name = "Raj",
            Department = "Development",
            Gender = "Male",
            Employees = new List<Person>()
                    {
                        new Person() {EmpID = 105, Name = "Kaliya", Department = "Development",Gender = "Male"},
                        new Person() {EmpID = 103, Name = "Emma Watson", Department = "Development",Gender = "Female"},

                    }
        }
    };

    List<Person> result = BossList
    .SelectMany(x =>
        new[] { new Person { Name = x.Name, Department = x.Department, Gender = x.Gender, EmpID = x.EmpID } }
        .Concat(x.Employees))
    .GroupBy(x => x.EmpID) //Group by employee ID
    .Select(g => g.First()) //And select a single instance for each unique employee
    .ToList();

    List<Person> SelectedResult = new List<Person>();

    // AsParallel() - Before Where Clause
    SelectedResult = result.AsParallel().Where(m => m.Name.ToLowerInvariant().Contains("Raj".ToLowerInvariant())).ToList();


    // AsParallel() - After Where Clause
    SelectedResult = result.Where(m => m.Name.ToLowerInvariant().Contains("Raj".ToLowerInvariant())).AsParallel().ToList();
}

Core Source Code: 核心源代码:

    List<Person> SelectedResult = new List<Person>();

    // AsParallel() - Before Where Clause
    SelectedResult = result.AsParallel().Where(m => m.Name.ToLowerInvariant().Contains("Raj".ToLowerInvariant())).ToList();


    // AsParallel() - After Where Clause
    SelectedResult = result.Where(m => m.Name.ToLowerInvariant().Contains("Raj".ToLowerInvariant())).AsParallel().ToList();

Before. 之前。

AsParallel helps us to run queries in parallel, which is enabling parallel threads to improve performance. AsParallel帮助我们并行运行查询,这使并行线程能够提高性能。 If you put before WHERE clause the filtering will be done in series, and only then will anything be parallelized. 如果放在WHERE子句之前,过滤将按顺序进行,只有这样才能并行化。

Here is some test code: 这是一些测试代码:

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

class AsParallelTest
{
    static void Main()
    {
        var query = Enumerable.Range(0, 1000)
                              .Select(ProjectionExample)
                              .Where(x => x > 10)
                              .AsParallel();

        Stopwatch stopWatch = Stopwatch.StartNew();
        int count = query.Count();
        stopWatch.Stop();

        Console.WriteLine("Count: {0} in {1}ms", count,
                          stopWatch.ElapsedMilliseconds);

        query = Enumerable.Range(0, 1000)
                          .AsParallel()
                          .Select(ProjectionExample)
                          .Where(x => x > 10);

        stopWatch = Stopwatch.StartNew();
        count = query.Count();
        stopWatch.Stop();

        Console.WriteLine("Count: {0} in {1}ms", count,
                       stopWatch.ElapsedMilliseconds);
   }

   static int ProjectionExample(int arg)
   {
       Thread.Sleep(10);
       return arg;
   }
}

Result: 结果:

Count: 989 in 10574ms
Count: 989 in 1409ms

It's obvious that the first result hasn't been parallelized, where the second has. 很明显,第一个结果没有被并行化,第二个结果就是第二个结果。 If you have only one processor core, the results should be close. 如果您只有一个处理器核心,则结果应该接近。 If you have more than two processor cores, the AsParallel call may increase performance even more. 如果您有两个以上的处理器核心,AsParallel调用可能会进一步提高性能。 Also, you can read this article. 此外,您可以阅读这篇文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM