编程语言的发展趋势及未来方向(6):并发
文件,把它转化成一系列对象,并存放在一个List中。然后对其执行一个LINQ语句,查找所有在华盛顿名叫Robert的人,再根据年份进行排序:
Console.WriteLine("Loading XML data...");
var popNames =
(from e in XElement.Load("popnames.xml").Elements("Name")
select new
{
Name = (string)e.Attribute("Name"),
State = (string)e.Attribute("State"),
Year = (int)e.Attribute("Year"),
Count = (int)e.Attribute("Count")
})
.ToList();
Console.WriteLine(popNames.Count + " records");
Console.WriteLine();
string targetName = "Robert";
string targetState = "WA";
var querySequential =
from n in popNames
where n.Name == targetName && n.State == targetState
orderby n.Year
select n;
我们来执行一下……首先加载XML文件,然后进行查询。利用PLINQ我们可以做到并行地查询。我们只要拷贝一份代码……改成queryParallel……现在我唯一要做的只是在数据源上使用AsParallel扩展方法,这样便会引入一套新的类型和实现,此时相同的LINQ操作使用的便是并行的实现:
var queryParallel =
from n in popNames.AsParallel()
where n.Name == targetName && n.State == targetState
orderby n.Year
select n;
我们重新执行两个查询。
![](../img/eep/emb/emb-74956gjiiz1bnldu.png)
再次加载XML数据……并行实现使用了1.5秒,我们再试着运行一次,一般结果会更好一些,现在可能刚好在执行一些后台任务。一般我们可以得到更快的结果……这次比较接近了。现在你可以观察到,我们并不需要做太多事情,便可以在我的双核机器上得到并发的效果。
![](../img/eep/emb/emb-74957zlodfg13h2b.png)
这里我无法保证说,我们只要随时加上AsParallel便可以得到两倍的性能,有时可以有时不行,有些查询能够被并行,有的则不可以。然而,我想你一定同意一点,使用如LINQ这样的DSL能够方便我们编写并行的代码,也更有可能利用起并行效果。虽然不是每次都有效,但是尝试的成本也很低。如果我们使用普通的for循环来编写代码,在某个地方使用线程池等等,便很容易在这些API里失去方向。而这里我们只要简单地尝试一下,便能知道是否可以提高性能了。
![](../img/eep/emb/emb-749582hi5anzlmhv.png)
这里你已经看到我使用的LINQ查询,而现在也有很多工作是通过循环来完成的。你可以想象主要的运算是从哪里来的,很自然会是在循环里操作数据。如果循环的每个迭代都是独立的,便有很大的机会可以利用并发操作──我知道这里是“如果”,不过长期来看则一定会出现这样的情况。这时候便可以使用并行扩展,或者说是.NET并行扩展里的新API,把循环转化成并行的循环,只要简单的改变……几乎只要用同样的循环体把for重构成Parallel.For就行了。如果你有foreach操作就可以使用Parallel.ForEach,或是一系列顺序执行的语句也可以用上Parallel.Invoke。此时任务并行库会接管并执行这些任务,根据你的CPU数量使用最优化的线程数量,你不需要关注更深的细节,只需要编写逻辑就可以了。
![](../img/eep/emb/emb-74959ypiuof5au1n.png)
就像我说的那样,可能你会有独立的任务但也可能没有,所以很多时候我们需要编程语言来关注这方面的事情。比如“隔离性(Isolation)”。例如,编译器如何发现这段代码是独立的,可以安全地并发执行,好比我创建了一个对象,在分享给其他人之前,我对它的改变是安全的。但是我一旦把它们共享出去了,那么它们便不安全了。所以如果我们的类型系统可以跟踪到这样的共享,如Linear Types──这在学术界也有一些研究。我们也可以在函数的纯洁性(Purity)方面下功夫,如关注某个函数是否有副作用,有些时候编译器可以做这方面的检查,它可以禁止某些操作,以此保证我们写出纯函数。还有便是不可变性(Immutability),目前的C#或VB,我们需要额外的工作才能写出不可变的代码──但本不该这样,我们应该在语言层面上更好的支持不可变性。这些都是在并发方面需要考虑的问题。
如果说有哪个语言特性超出这个范畴,我想说这里还有一个原则:你不该期望C#中出现某个特别的并发模型,而应该是一种通用的,可用于各种不同的并发场景的特性,
编程语言 相关文章:
- 编程语言的发展趋势及未来方向(7):总结(04-19)
- PLC的编程语言and基本指令系统(12-15)
- 9月Tiobe编程语言排行榜公布(09-12)
- 用VB 编程语言实现PC机与AVR 单片机的通信(12-09)
- 基于IEC61131标准编程语言的Phoenix Contact自动控制系统(04-13)
- 单片机的“语言”规范(01-26)