【问题标题】:AsParallel - Before vs After in Linq Where Clause PerformanceAsParallel - Linq Where 子句性能中的前后对比
【发布时间】:2016-03-10 05:26:36
【问题描述】:

我有一个List<Boss> 收藏,每个老板都有 2 到 10 名助理人员。我正在对包括老板在内的所有员工进行分组。现在我有 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();
}

核心源代码:

    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();

【问题讨论】:

  • 在这个例子中,使用 AsParallel 实在是太过分了。你读过this 页面吗?您能否提供有关您的实际问题的更多信息(例如:实际上所有内容都在 SqlServer 数据库中),
  • 您应该对其进行基准测试。其余的纯属猜测。

标签: c# linq plinq


【解决方案1】:

之前。

AsParallel 帮助我们并行运行查询,这使并行线程能够提高性能。如果您在 WHERE 子句之前放置过滤将按顺序完成,然后才会并行化。

这是一些测试代码:

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;
   }
}

结果:

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

很明显,第一个结果没有被并行化,而第二个结果已经并行化了。如果您只有一个处理器内核,结果应该很接近。如果您有两个以上的处理器内核,则 AsParallel 调用可能会进一步提高性能。 另外,您可以阅读this 文章。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多