巴别塔上的雇工


“重大设计决策失误”
4月 4, 2009, 12:40 上午
Filed under: 技术体会

和以前部门的同事聊,都觉得以前犯了几个“重大设计决策失误”:第一,使用了LINQ,第二,使用了WCF。这两个都是被宣传得天花乱坠的技术,使用它们怎么会被认为是缺陷呢?

LINQ和WCF都体现了很好的软件思维,但是并不是适合任何场合,比如,对于效率要求高和I/O特别频繁的场合,LINQ和WCF就有问题了。

LINQ

LINQ,全称Language Integrated Query,C# 2.0还只是增加了一批不是很相关的feature,但C# 3.0增加的几乎所有feature都是为了一个feature服务——LINQ,所以很难界定怎么样的coding算是使用了LINQ。写SQL语句模样的LINQ query expression当然算是使用LINQ,只用lambda expression也可以说是使用LINQ,这里我们说的“重大缺陷”指的是用LINQ query expression来处理IEnumerable<T>。

LINQ还是体现了很棒的软件思维,但是效率上有些问题。访问一个数组或者List的速度要比访问一个IEnumerable<T>要快,首先访问IEnumerable<T>不可能用indexing的方式访问某个位置上的元素,只能从头开始找,其次,就算是一个从头到尾的遍历,访问IEnumrable<T>也要比访问数组或者List慢,因为访问IEnumerable<T>要先获得IEnumrator<T>,然后不断地调用MoveNext()函数和Current属性。总之,和操作数组和List相比,使用LINQ去操作IEnumerable<T>会慢。

LINQ这头牛吃进去的是IEnumerable<T>的草,挤出来的是IEnumerable<T>的奶(为了简单,我就忽略LINQ可以吞其他类型数据的事实了),这样即使我们已经获得了一个数组,经LINQ一操作,我们得到的是IEnumerable<T>,丧失了输入类型是数组的好处。当然我们可以再ToArray一把,但是这样带来的浪费更大。

还有,LINQ expression不能异步运行(Asynchronous),这几乎就是决定LINQ在涉及到I/O上无法scale,LINQ to SQL被毙掉也可以理解了。

这是.NET专家Jeff Richter在培训课上被问了很多关于LINQ的缺点的问题之后的原话:

“After you guys asked these questions, it seems LINQ is NOT that good.”

WCF

WCF全称Windows Communication Foundation,是.NET 3.0推出的四个Library之一。本来出发点挺好,让程序可以只使用一种API,底层可以使用任意一种Binding方式,假如一开始使用HTTP作为通讯方式(HTTP Binding),过一阵子想直接用TCP/IP来提高速度,之前的code不用改变,因为WCF把底层给抽象(Abstraction)了嘛。

对于Abstraction,最讨厌的就是有Abstraction Leakage,也就是说没有抽象好,漏了,让上层还是被迫了解被抽象的东东是怎么回事。WCF就存在Abstaction Leakage,当调换底层Binding的时候,并不能保证上面完全没有知觉。

WCF还有一个大问题,client端获得一个server的proxy,然后通过这个proxy往server发请求,而且还支持异步(这点比LINQ做得好,eh)。问题是,WCF规定,一个proxy上如果抛出一个Exception,那么表示这个proxy坏了,不能再用了,好,现在client端通过一个proxy依次异步发送3个请求A、B、C,Server端成功处理了B和C,但是对A失败了,返回一个错误,而且这个错误信息赶在B和C的成功信息之前回到了proxy,那么按照WCF,B和C也无法获得结果,因为A的失败导致这个proxy进入失败状态。

********

LINQ和WCF都是很多软件工程师的心血结晶,我不是说它们烂得不能用,只是提醒它们没有你想象的那么好。当你使用一种技术的时候,你就依赖了这种技术,之后它的成败就会影响你的成败,所以不要只是看一个技术被宣传的优点,也要看到它的缺点,知己知彼才能百战不殆。


3条评论 so far
留下评论

我们就在用WCF做sharepointonline…

评论 由 kit

使用WCF感觉怎么样?

评论 由 Morgan

WCF到没啥感觉给我们提供WCF service的那个team实在不能忍

评论 由 kit




留下评论