我有一个List<Boss>
收藏品,每个Boss都有2到10个助理员工。我正在将包括Boss在内的所有员工分组。现在我有List<Person>
,我正在使用并行LINQ 搜索“Raj”,在哪里可以放置支持方法AsParallel()
在Where 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();
答案 0 :(得分:5)
在
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文章。