C# PLinq并行求和性能不一致

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

我有以下代码来测试PLinq计算数字的速度比Linq快多少:

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
和simple
foreach
<与LINQ相比,code>foreach几乎总是更快。至少要做一个公平的比较。@GertArnold不,我是在将一个简单的foreach循环与PLinq进行比较,而不是与Linq进行比较
private static IEnumerable<Company> GenerateSmallCompanies()
{
    return Enumerable
        .Range(0, 10000000)
        .Select(number => new Company {EvaluatedMarketValue = number});
}