PLinq并行求和性能不一致

时间:2015-10-25 09:44:48

标签: 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");
        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;
    }
}

结果不符合预期,当它只是十进制数字时,PLinq更快,但当数字包装在小公司对象中时,PLinq更慢,这里是日志:

just decimals
one thread
 Time: 562
plinq many threads
 Time: 525
one thread
 Time: 569
plinq many threads
 Time: 460
one thread
 Time: 573
plinq many threads
 Time: 283
one thread
 Time: 570
plinq many threads
 Time: 193
one thread
 Time: 548
plinq many threads
 Time: 194
one thread
 Time: 525
plinq many threads
 Time: 174
one thread
 Time: 524
plinq many threads
 Time: 137
one thread
 Time: 555
plinq many threads
 Time: 153
one thread
 Time: 535
plinq many threads
 Time: 145
one thread
 Time: 554
plinq many threads
 Time: 159
decimals in wrapper objects
==========================
one thread
 Time: 762
plinq many threads
 Time: 2880
==========================
one thread
 Time: 719
plinq many threads
 Time: 2915
==========================
one thread
 Time: 686
plinq many threads
 Time: 2924
==========================
one thread
 Time: 690
plinq many threads
 Time: 2919
==========================
one thread
 Time: 697
plinq many threads
 Time: 2928
==========================
one thread
 Time: 710
plinq many threads
 Time: 2984
==========================
one thread
 Time: 700
plinq many threads
 Time: 2986
==========================
one thread
 Time: 723
plinq many threads
 Time: 3054
==========================
one thread
 Time: 779
plinq many threads
 Time: 3030
==========================
one thread
 Time: 756
plinq many threads
 Time: 2901

是什么原因?太多小物件? GC

1 个答案:

答案 0 :(得分:0)

var markerGroup = L.featureGroup;
markerGroup.addTo(map)
//For each marker, .addTo(markerGroup)
markerGroup.on('click', function (event) {
    var modalDiv = "<div class='modal fade'.... [(docs)][1]
    $(modalDiv).modal({})
})

发现问题,就是这种方法。 在这里它做懒惰的评估,最后添加ToList或ToArray,Plinq会快得多。