C# PLinq并行求和性能不一致
我有以下代码来测试PLinq计算数字的速度比Linq快多少:C# PLinq并行求和性能不一致,c#,.net,linq,task-parallel-library,plinq,C#,.net,Linq,Task Parallel Library,Plinq,我有以下代码来测试PLinq计算数字的速度比Linq快多少: internal class Program { private static readonly IEnumerable<Company> _smallCompanies = GenerateSmallCompanies(); private static void Main(string[] args) { Console.WriteLine ("just decimals");
internal class Program
{
private static readonly IEnumerable<Company> _smallCompanies = GenerateSmallCompanies();
private static void Main(string[] args)
{
Console.WriteLine ("just decimals");
var numbers=Enumerable.Range (0, 10000000).Select(n=>(decimal)n).ToList();
for (int i = 0; i < 10; i++) {
Console.WriteLine ("one thread");
Timer (()=>numbers.Aggregate((a,b)=>a+b));
Console.WriteLine ("plinq many threads");
Timer (()=>numbers.AsParallel().Aggregate(decimal.Zero,(a,b)=>a+b,(r1,r2)=>r1+r2,f=>f));
}
Console.WriteLine ("decimals in wrapper objects");
for (int i = 0; i < 10; i++) {
WithWrappers ();
}
}
private static void Timer(Action act){
var stopwatch = new Stopwatch();
stopwatch.Start();
act ();
stopwatch.Stop();
Console.WriteLine( " Time: " +
stopwatch.ElapsedMilliseconds);
}
private static void WithWrappers()
{
Console.WriteLine("==========================");
PrintMergeResult(LinearMerger.LinearMerge, "one thread");
PrintMergeResult(FunctionalParallelMerger.FunctionalParallelMerge, "plinq many threads");
}
private static void PrintMergeResult(Func<Company, IEnumerable<Company>, Company> mergeMethod,
string funcApproach)
{
Console.WriteLine(funcApproach);
Timer (() => mergeMethod (new Company { EvaluatedMarketValue = 0 }, _smallCompanies));
}
private static IEnumerable<Company> GenerateSmallCompanies()
{
return Enumerable
.Range(0, 10000000)
.Select(number => new Company {EvaluatedMarketValue = number});
}
}
internal class Company
{
public decimal EvaluatedMarketValue { get; set; }
public Company Merge(Company that)
{
EvaluatedMarketValue += that.EvaluatedMarketValue;
return this;
}
}
internal class FunctionalParallelMerger
{
public static Company FunctionalParallelMerge(Company bigCompany, IEnumerable<Company> smallCompanies)
{
return smallCompanies
.AsParallel()
.Aggregate(CreateShell,
(shell, smallCompany) => shell.Merge(smallCompany),
(shell1, shell2) => shell1.Merge(shell2),
bigCompany.Merge);
}
private static Company CreateShell()
{
return new Company();
}
}
internal class LinearMerger
{
public static Company LinearMerge(Company bigCompany, IEnumerable<Company> smallCompanies)
{
foreach (var smallCompany in smallCompanies)
{
bigCompany.Merge(smallCompany);
}
return bigCompany;
}
}
原因是什么?太多的小物体?GC?私有静态IEnumerable GeneratesMallCompanys()
private static IEnumerable<Company> GenerateSmallCompanies()
{
return Enumerable
.Range(0, 10000000)
.Select(number => new Company {EvaluatedMarketValue = number});
}
{
返回可枚举
.范围(0,10000000)
.Select(number=>newcompany{EvaluatedMarketValue=number});
}
发现问题,就是这个方法。
在这里,它正在执行惰性求值、添加ToList或ToArray。最后,Plinq将快得多。在我的计算机中,对于包装对象中的
小数
给出了这个结果<代码>一个线程739和多个线程763
。但是对于仅小数
我得到的结果与您比较两个完全不同的函数时得到的结果相同,Aggregate
和simpleforeach
<与LINQ相比,code>foreach几乎总是更快。至少要做一个公平的比较。@GertArnold不,我是在将一个简单的foreach循环与PLinq进行比较,而不是与Linq进行比较
private static IEnumerable<Company> GenerateSmallCompanies()
{
return Enumerable
.Range(0, 10000000)
.Select(number => new Company {EvaluatedMarketValue = number});
}