本文发表在 rolia.net 枫下论坛废话不多说了,先看一段小程序
假设我有一个目录,
string folder = @\"c:\\xxxx\";
里面有数十个子目录,这数十个子目录里面有成百上千个.txt文件,我想遍历这所有的.txt文件,并把其中包含“Hello World!” string 的行都挑出来放在一个数组 Array里面。于是写了这么个小程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;
static void Lab2()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string folder = @\"c:\\xxxx\";
var rawLines =
Directory.GetFiles(folder, \"*.txt\", SearchOption.AllDirectories)
.SelectMany(file =>(new FileInfo(file)).LoadRawlines()
.Where(s => s.Contains(\"Hello World!\"))).ToArray();
Console.WriteLine(rawLines);
stopWatch.Stop();
Console.WriteLine(\"done.. time lasted: \"+stopWatch.Elapsed.ToString());
}
这是按照正常的LINQ写法来写的,扫描1100个文件,170个Folder,450M .txt 文件,所用时间 52秒
然后,把中间的代码换成PLINQ方式,改成
var rawLines =
Directory.GetFiles(folder, \"*.txt\", SearchOption.AllDirectories)
.AsParallel().SelectMany(file =>
(new FileInfo(file)).LoadRawlines()
.AsParallel()
.Where(s => s.Contains(\"Hello World!\"))).ToArray();
再次运行,时间为24.8秒,整个查询速度快了1倍以上,而我所作的修改只不过是加了.AsParallel()这么个修饰符,不要小看这个AsParallel(),加上这个修饰符之后,.net的LINQ查询就会工作在并行方式之下,充分利用你的CPU资源,不对,不能说充分,是100%地榨光你的CPU资源,以至于其他的运行在同一台计算机上的程序会变得非常缓慢,这可能是PLINQ的唯一一个缺点
PLINQ在查询小数量的数据的时候速度反而会慢于普通的LINQ,但是如果涉及到大批量的数据处理,效率会成倍提高
程序中这条语句
(new FileInfo(file)).LoadRawlines() ,是我自己写的一个扩展方法,目的是读出一个.txt文件中的所有strings 定义如下:
public static List<string> LoadRawlines(this System.IO.FileInfo fileInfo)
{
List<string> result = new List<string>();
using (System.IO.StreamReader sr = new System.IO.StreamReader(fileInfo.FullName))
{
string s;
while ((s = sr.ReadLine()) != null)
{
result.Add(s);
}
}
return result;
}
怎样高效运用CPU的并行处理能力是很多公司比如Google等倾尽全力奋斗的目标,现在被微软一个AsParallel()就搞定了,真是神奇
Parallel和PLINQ已经是.Net 4.0的基本装备,等VS 2010出来就好了更多精彩文章及讨论,请光临枫下论坛 rolia.net
假设我有一个目录,
string folder = @\"c:\\xxxx\";
里面有数十个子目录,这数十个子目录里面有成百上千个.txt文件,我想遍历这所有的.txt文件,并把其中包含“Hello World!” string 的行都挑出来放在一个数组 Array里面。于是写了这么个小程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Threading;
static void Lab2()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string folder = @\"c:\\xxxx\";
var rawLines =
Directory.GetFiles(folder, \"*.txt\", SearchOption.AllDirectories)
.SelectMany(file =>(new FileInfo(file)).LoadRawlines()
.Where(s => s.Contains(\"Hello World!\"))).ToArray();
Console.WriteLine(rawLines);
stopWatch.Stop();
Console.WriteLine(\"done.. time lasted: \"+stopWatch.Elapsed.ToString());
}
这是按照正常的LINQ写法来写的,扫描1100个文件,170个Folder,450M .txt 文件,所用时间 52秒
然后,把中间的代码换成PLINQ方式,改成
var rawLines =
Directory.GetFiles(folder, \"*.txt\", SearchOption.AllDirectories)
.AsParallel().SelectMany(file =>
(new FileInfo(file)).LoadRawlines()
.AsParallel()
.Where(s => s.Contains(\"Hello World!\"))).ToArray();
再次运行,时间为24.8秒,整个查询速度快了1倍以上,而我所作的修改只不过是加了.AsParallel()这么个修饰符,不要小看这个AsParallel(),加上这个修饰符之后,.net的LINQ查询就会工作在并行方式之下,充分利用你的CPU资源,不对,不能说充分,是100%地榨光你的CPU资源,以至于其他的运行在同一台计算机上的程序会变得非常缓慢,这可能是PLINQ的唯一一个缺点
PLINQ在查询小数量的数据的时候速度反而会慢于普通的LINQ,但是如果涉及到大批量的数据处理,效率会成倍提高
程序中这条语句
(new FileInfo(file)).LoadRawlines() ,是我自己写的一个扩展方法,目的是读出一个.txt文件中的所有strings 定义如下:
public static List<string> LoadRawlines(this System.IO.FileInfo fileInfo)
{
List<string> result = new List<string>();
using (System.IO.StreamReader sr = new System.IO.StreamReader(fileInfo.FullName))
{
string s;
while ((s = sr.ReadLine()) != null)
{
result.Add(s);
}
}
return result;
}
怎样高效运用CPU的并行处理能力是很多公司比如Google等倾尽全力奋斗的目标,现在被微软一个AsParallel()就搞定了,真是神奇
Parallel和PLINQ已经是.Net 4.0的基本装备,等VS 2010出来就好了更多精彩文章及讨论,请光临枫下论坛 rolia.net