一直很忙,压了很多贴,今天发一篇吧。后面的看心情吧。
今天群里有人问如何解析web.config方便,然后我就推荐了Linq to XML,然后就有人说“我宁可XmlDocument,再SeleteNodes和SeleteNode”,不要用LINQ之类的,甚至否定EntityFramework等一系列框架,认为这些都是所谓的“懒人技术”,都是以牺牲性能为代价的。我在这里想申明一点,没有测试就没有发言权,并不是所有的”懒人技术“都是以牺牲性能为代价的。我这人比较喜欢就技术论技术,不喜欢武断的言论,于是展开了讨论。本文只是做一个总结。
很多同学已经做过性能测试了,我就不重复了,如下链接:
XML数据读取方式性能比较(一)
从上面的结果我们不能看出,Linq to Xml的性能明显是优于XmlDocument的。我这人比较喜欢追根溯源,如果单从这个,总是有人会产生各种悖论,比如:
【码帅】-------- 13:52:01
确定真是LINQ高吗
【码奴】-------- 13:52:32
什么高?
【码帅】-------- 13:52:42
为什么上面2个都有Add
【码帅】-------- 13:52:49
下面2个都没有
【码帅】-------- 13:52:54
这测试公正吗
【码帅】-------- 13:53:18
好比一个是直接new Object[]
【码帅】-------- 13:54:38
4个测试就有问题
【码帅】-------- 13:56:03
2个40多秒的都有这Add
其实他的问题都没到点上,这里根本就不是Add的问题,Linq的ToList()方法肯定也干了这事,如果怀疑这里,完全可以自己去写个测试。所以我觉得有必要说下为什么LINQ to XML性能优于XmlDocument的缘由了。
首先,我们需要明白的一点是:
LINQ to XML有一位优秀的母亲——XmlReader。
LINQ to XML 在 XmlReader 基础之上实现的,也就是LINQ to XML源于XmlReader,高于XmlReader。
遗传基因很重要!
XmlReader 是一种快速的只进非缓存分析器。他丫的对XML 数据流的访问是只读的。
其次,LINQ to XML有一位出色的父亲——Linq。
LINQ to XML 的一个最重要的性能优势(与 XmlDocument 相比)为:LINQ to XML 中的查询是静态编译的,而 XPath 查询则必须在运行时进行解释。
这个因素是性能中至关重要的,所谓”子不教,父之过“!
也就是说,LINQ to XML的查询被编译成静态链接的方法调用,这样的性能提升是巨大的。反观XmlDocument,它在每次调用 SelectNodes 方法时,都必须在内部执行以下操作:
与相应的 LINQ to XML 查询完成的工作相比,这需要执行非常多的工作。
除此之外,LINQ to XML还继承了父亲的延迟执行的优良传统,也能够提高性能。
父亲这么优秀,XmlDocument自然无法相比了。
所以,富二代和官二代起点就比你高,你如果不比他们多付出N倍的努力,你甚至连他们的起点都无法到达。
科普下延迟执行的知识:
延迟执行意味着表达式的计算延迟,直到真正需要它的实现值为止。 当必须操作大型数据集合,特别是在包含一系列链接的查询或操作的程序中操作时,延迟执行可以大大改善性能。 在最佳情况下,延迟执行只允许对源集合的单个循环访问。
LINQ 技术广泛应用了延迟执行,包括在核心 System.Linq 类的成员和不同 LINQ 命名空间中的扩展方法(如 System.Xml.Linq.Extensions)中使用。
除了上面的,其他的还有些他在成长过程中,自己提升的优点,比如:XName 和 XNamespace 对象是原子化的,如果这两个对象包含相同的名字,则它们会引用同一个对象。 也就是说当比较两个原子化名称是否相等时,只需确定这两个引用是否指向同一个对象,而不必进行很”耗费时间“的字符串比较,这个是有助于性能提升的。
虽然这不是拍电影,但是尾声还是必须的。