LINQ (LINQ) Language Integrated Query 可以方便的查询并处理不同数据源的数据。PLINQ Parallel LINQ不光拥有LINQ的功能,还添加了并行操作的接口,以方便使用并提高效率。
更详细的信息: https://msdn.microsoft.com/zh-cn/library/dd460688(v=vs.110).aspx
用一个简单的例子足以说明PLINQ的使用。
简单的说明:
第一部分:先在一个文档中查询包含字母 “a”的单词首先使用 LINQ进行查询10000次,然后使用PLINQ进行同样的测试,看看效率有多少提高。 AsParallel() 是主要用到的接口。
第二部分:计算Short类型所有数字的和,同样测试两次使用LINQ和PLINQ。
第三部分:测试PLINQ的查找排序功能。使用的接口分别为AsOrdered()和orderby
AsOrdered:保持数据在数据源中的顺序不变。
orderby:按用户指定的顺序进行排序,升序/降序
示例程序:
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Linq;
using System.IO;
namespace Sample6_1_plink_basic
{
class Program
{
static int SumDefault(int[] array)
{
return array.Sum();
}
static int SumAsParallel(int[] array)
{
return array.AsParallel().Sum();
}
static string[] words = { "Day", "Car", "Land", "Road", "Sea", "Mountain", "River"};
static void Main(string[] args)
{
var customers = System.IO.File.ReadAllLines(@"D:\testdir\CSParallel_Program\Sample6-1 plink basic\target.txt");
int nCounter = 0;
Console.WriteLine("============================================================");
Console.WriteLine("TEST NORMAL LINQ");
Console.WriteLine("============================================================");
var swatchpn = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
{
var normalkeyLetters = from line in customers
let keys = line.Split(‘ ‘)
from key in keys
where (key.Contains(‘a‘))
select key;
var normalkeyList = normalkeyLetters.ToList();
nCounter = normalkeyList.Count();
}
swatchpn.Stop();
Console.WriteLine("Word with letter a = {0}", nCounter);
Console.WriteLine("LINQ Use Time: {0}", swatchpn.Elapsed);
Console.WriteLine("\n\n");
Console.WriteLine("============================================================");
Console.WriteLine("TEST PARALLEL LINQ");
Console.WriteLine("============================================================");
nCounter = 0;
var swatchp = Stopwatch.StartNew();
for (int i = 0; i < 10000; i++)
{
var keyLetters = from line in customers.AsParallel()
let keys = line.Split(‘ ‘)
from key in keys.AsParallel()
where (key.Contains(‘a‘))
select key;
var keyList = keyLetters.ToList();
nCounter = keyList.Count();
}
swatchp.Stop();
Console.WriteLine("Word with letter a = {0}", nCounter);
Console.WriteLine("PLINQ Use Time: {0}", swatchp.Elapsed);
// Generate array.
int[] array = Enumerable.Range(0, short.MaxValue).ToArray();
const int m = 10000;
var s1 = Stopwatch.StartNew();
for (int i = 0; i < m; i++)
{
SumDefault(array);
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < m; i++)
{
SumAsParallel(array);
}
s2.Stop();
Console.WriteLine("\n\n");
Console.WriteLine("============================================================");
Console.WriteLine("CALCULATE SUMMARY TEST");
Console.WriteLine("============================================================");
Console.WriteLine("Default Summary: " + ((double)(s1.Elapsed.TotalMilliseconds * 1000000) / m).ToString("0.00 ns"));
Console.WriteLine("Parallel Summary: " + ((double)(s2.Elapsed.TotalMilliseconds * 1000000) /m).ToString("0.00 ns"));
Console.WriteLine("\n\n");
Console.WriteLine("============================================================");
Console.WriteLine("Parallel ASOrder Test");
Console.WriteLine("============================================================");
var orderwords = from word in words.AsParallel().AsOrdered()
where (word.Contains(‘a‘))
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("Parallel OrderBy Test");
Console.WriteLine("============================================================");
var orderbywords = from word in words.AsParallel()
where (word.Contains(‘a‘))
orderby word ascending
select word;
var orderbyletterList = orderbywords.ToList();
for (int i = 0; i < orderbyletterList.Count; i++)
{
Console.WriteLine(orderbyletterList[i]);
}
Console.ReadKey();
}
}
}
测试结果:
测试其实运行过多次,关于单词的测试LINQ的结果在32至34秒,PLINQ大概在16至19秒,大约有50%的提升。
PLINQ使用多个任务对同一个数据源进行处理,然后汇总,使得效率提高。但并行执行的任务应该处理数据的哪个部分,怎样对数据进行合理的划分,并且分配给任务是很重要的,它会严重的影响效率。但开发者并不太可能去真正的控制PLINQ去采用哪种分区方式,了解一下它的内部机理在优化程序性能时会有一定的帮助。
PLINQ中有四种数据的划分方式:
原文地址:http://blog.csdn.net/wangzhiyu1980/article/details/46224627