.Net 中Partitioner static与dynamic的性能对比

来源:互联网 发布:软件著作权登记办理 编辑:程序博客网 时间:2024/05/04 15:01

先看LINQ的方式,dynamic的方式:

void Main(){// testing setupvar source = Enumerable.Range(0, 10000000).ToArray();double[] results = new double[source.Length];Console.WriteLine("creating partitioner in LINQ way...");var dt = DateTime.Now;var partitionerLinq = Partitioner.Create(source, true);Console.WriteLine("creating partitioner in LINQ done, ticks: " + (DateTime.Now - dt).Ticks);dt = DateTime.Now;var r = partitionerLinq.AsParallel().Select(x => x * x * Math.PI).ToList();Console.WriteLine("LINQ way done , ticks:" + (DateTime.Now - dt).Ticks);dt =  DateTime.Now;for(var i = 0;i < source.Length; i++){results[i] = source[i] * Math.PI;}Console.WriteLine("processing by single thread done, ticks : " + (DateTime.Now - dt).Ticks);}




LINQPAD输出:
creating partitioner in LINQ way...creating partitioner in LINQ done, ticks: 0LINQ way done , ticks:3472754processing by single thread done, ticks : 380298


可见,动态分配chunk的partition基本比单线程的普通实现慢了10倍!


再看静态的方式:

void Main(){// testing setupvar source = Enumerable.Range(0, 10000000).ToArray();double[] results = new double[source.Length];Console.WriteLine("creating partitioner in a way processing as static range ..");var dt = DateTime.Now;// Partition the entire source array.var rangePartitioner = Partitioner.Create(0, source.Length);Console.WriteLine("created partitioner, ticks:" + (DateTime.Now - dt).Ticks);dt =  DateTime.Now;// Loop over the partitions in parallel.Parallel.ForEach(rangePartitioner, (range, loopState) =>{// Loop over each range element without a delegate invocation.for (int i = range.Item1; i < range.Item2; i++){results[i] = source[i] * source[i] * Math.PI;}});Console.WriteLine("processing by range partitioner done, ticks : " + (DateTime.Now - dt).Ticks);dt =  DateTime.Now;for(var i = 0;i < source.Length; i++){results[i] = source[i] * Math.PI;}Console.WriteLine("processing by single thread done, ticks : " + (DateTime.Now - dt).Ticks);}// Define other methods and classes here




LINQPAD输出:

creating partitioner in a way processing as static range ..created partitioner, ticks:0processing by range partitioner done, ticks : 185180processing by single thread done, ticks : 375279


基本上,静态partition的方式比普通方式快两倍。


现在,依然使用静态方式,把数据量增大10倍,看LINQ输出:

creating partitioner in a way processing as static range ..created partitioner, ticks:0processing by range partitioner done, ticks : 1951457processing by single thread done, ticks : 3808162




可以看到,时间差别依然差不多是一倍的速度。




总结,当考虑使用Partition时,最好使用静态方式;并且处理逻辑不建议过于复杂(MSDN建议:In general, range partitioning is only faster when the execution time of the delegate is small to moderate);不过这一点还有待测试,暂时没有想出合适的logic来测试。
1 0
原创粉丝点击