C# AsParallel-Linq Where子句中的前后性能
我有一个C# AsParallel-Linq Where子句中的前后性能,c#,linq,plinq,C#,Linq,Plinq,我有一个列表集合,每个老板都有2到10名助理员工。我把所有的员工都分组,包括老板。现在我有了列表,从这里我使用并行LINQ搜索“Raj”,在where子句之前或之后,我可以在哪里放置支持方法aspallel(),以获得更好的性能 public class Person { public int EmpID { get; set; } public string Name { get; set; } public string Department { get; set;
列表
集合,每个老板都有2到10名助理员工。我把所有的员工都分组,包括老板。现在我有了列表
,从这里我使用并行LINQ搜索“Raj”,在where子句之前或之后,我可以在哪里放置支持方法aspallel()
,以获得更好的性能
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();
}
公共类人物
{
公共int EmpID{get;set;}
公共字符串名称{get;set;}
公共字符串部门{get;set;}
公共字符串{get;set;}
}
void Main()
{
List BossList=新列表()
{
新老板()
{
EmpID=101,
Name=“Harry”,
Department=“开发”,
性别=“男性”,
雇员=新名单()
{
新人(){EmpID=102,Name=“Peter”,Department=“Development”,Gender=“Male”},
新人(){EmpID=103,Name=“Emma Watson”,Department=“Development”,Gender=“Female”},
}
},
新老板()
{
EmpID=104,
Name=“Raj”,
Department=“开发”,
性别=“男性”,
雇员=新名单()
{
新人(){EmpID=105,Name=“Kaliya”,Department=“Development”,Gender=“Male”},
新人(){EmpID=103,Name=“Emma Watson”,Department=“Development”,Gender=“Female”},
}
}
};
列表结果=BossList
.SelectMany(x=>
新[]{newperson{Name=x.Name,Department=x.Department,Gender=x.Gender,EmpID=x.EmpID}}
.Concat(x名雇员))
.GroupBy(x=>x.EmpID)//按员工ID分组
.Select(g=>g.First())//并为每个唯一的员工选择一个实例
.ToList();
List SelectedResult=新建列表();
//AsParallel()-Before Where子句
SelectedResult=result.AsParallel()。其中(m=>m.Name.ToLowerInvariant()。包含(“Raj.ToLowerInvariant())。ToList();
//AsParallel()-Where子句之后
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();
List SelectedResult=new List();
//AsParallel()-Before Where子句
SelectedResult=result.AsParallel()。其中(m=>m.Name.ToLowerInvariant()。包含(“Raj.ToLowerInvariant())。ToList();
//AsParallel()-Where子句之后
SelectedResult=result.Where(m=>m.Name.ToLowerInvariant().Contains(“Raj.ToLowerInvariant()).AsParallel().ToList();
之前
AsParallel帮助我们并行运行查询,这使并行线程能够提高性能。如果将WHERE子句放在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调用可能会进一步提高性能。
此外,您还可以阅读本文。在本例中,使用AsParallel将是一种真正的过度使用。你读过佩奇吗?如果您能提供更多关于实际问题的信息(例如:实际上,一切都在SqlServer数据库中),您应该对其进行基准测试。剩下的纯粹是猜测。