您的位置:首页 > 编程语言 > C#

C# 并行编程 之 PLINQ并行度的指定 和 ForAll的使用

2015-06-05 09:03 405 查看

概要

每台计算机上的物理内核数目不一样,在程序并行运行时并不是运用的内核数越多越好。某些情况下根据实际情况动态的配置会达到更好的效果。

ForAll可以看做是 .NetFramework提供的一种提高效率简化编程的一种可选的操作。它本身就是并行的,主要针对的是处理无序的集合。

PLINQ指定并行度

指定并行度的API:WithDegreeOfParallelism(N),并行度并不是越大越好,如果运算时把CPU都占满了,很有可能影响GUI对用户的响应。

示例代码:

代码中指定了不同的并行度,并且对他们的运算时间进行了比较 分别指定为2 和 4。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

namespace Sample6_5_plinq_withdegreeofparallelism
{
class Program
{
static int NUM_INTS = 500000000;

static ParallelQuery<int> GenerateInputeData4Parallel()
{
return ParallelEnumerable.Range(1, NUM_INTS);
}

static void Main(string[] args)
{
var palTarget = GenerateInputeData4Parallel();
Console.WriteLine("============================================================");
Console.WriteLine("TEST PARALLEL LINQ:   Parallelism = 2");
Console.WriteLine("============================================================");
var swatchp2 = Stopwatch.StartNew();

var palQuery = (from intNum in palTarget.AsParallel().WithDegreeOfParallelism(2)
where ((intNum % 5) == 0)
select (intNum / Math.PI)).Average();
swatchp2.Stop();

Console.WriteLine("PLINQ Result: " + palQuery + "    LINQ Use Time: {0}", swatchp2.Elapsed);

palTarget = GenerateInputeData4Parallel();
Console.WriteLine("\n\n");
Console.WriteLine("============================================================");
Console.WriteLine("TEST PARALLEL LINQ:   Parallelism = 4");
Console.WriteLine("============================================================");
var swatchp4 = Stopwatch.StartNew();

palQuery = (from intNum in palTarget.AsParallel().WithDegreeOfParallelism(4)
where ((intNum % 5) == 0)
select (intNum / Math.PI)).Average();
swatchp4.Stop();

Console.WriteLine("PLINQ Result: " + palQuery + "    LINQ Use Time: {0}", swatchp4.Elapsed);
Console.ReadLine();
}
}
}


测试结果:

从测试结果上看,并行度不一样程序运行的时间差别还是很明显的。



PLINQ ForAll

单独理解ForAll比较麻烦,但用图把它和Foreach放到一起比较一下理解起来就简单了。

在 Foreach 的操作中,隐含的是在汇总每个任务的操作结果时对数据的顺序是有要求的,是按一定顺序进行的。但对于ForAll来说是没有要求的。在操作无序的数据时可以提高一定的效率。



示例代码:

代码很简单,就是找到含有a的字符串,并排序输出,输出以后把字符变为大写,这个操作使用ForAll来执行。

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Linq;
using System.IO;
using System.Collections.Concurrent;

namespace Sample6_6_plinq_forall
{
class Program
{
static string[] words = { "Day", "Car", "Land", "Road", "Sea", "Mountain", "River" };

static void Main(string[] args)
{
Console.WriteLine("============================================================");
Console.WriteLine("Parallel Test Ordered String");
Console.WriteLine("============================================================");
var orderwords = from word in words.AsParallel()
where (word.Contains('a'))
orderby word ascending
select word;

var orderletterList = orderwords.ToList();
for (int i = 0; i < orderletterList.Count; i++)
{
Console.WriteLine(orderletterList[i]);
}

Console.WriteLine("\n\n");
Console.WriteLine("============================================================");
Console.WriteLine("ForAll Result");
Console.WriteLine("============================================================");

ConcurrentBag<string> newForAllData = new ConcurrentBag<string>();
orderwords.ForAll((e) => newForAllData.Add(e.ToUpper()));
for (int i = 0; i < newForAllData.Count; i++)
{
Console.WriteLine(newForAllData.ElementAt(i));
}

Console.ReadLine();
}
}
}




从测试结果可以看出,当使用完ForAll后,输出的字符串并不是顺序的了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: