为什么LINQ to XML的性能要优于XmlDocument?
一直很忙,压了很多贴,今天发一篇吧。后面的看心情吧。
今天群里有人问如何解析web.config方便,然后我就推荐了Linq to XML,然后就有人说“我宁可XmlDocument,再SeleteNodes和SeleteNode”,不要用LINQ之类的,甚至否定EntityFramework等一系列框架,认为这些都是所谓的“懒人技术”,都是以牺牲性能为代价的。我在这里想申明一点,没有测试就没有发言权,并不是所有的”懒人技术“都是以牺牲性能为代价的。我这人比较喜欢就技术论技术,不喜欢武断的言论,于是展开了讨论。本文只是做一个总结。
LINQ to XML的性能测试
很多同学已经做过性能测试了,我就不重复了,如下链接:
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性能优于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 方法时,都必须在内部执行以下操作:
- 分析包含 XPath 表达式的字符串,并将字符串划分成多个标记。
- 验证这些标记以确保 XPath 表达式有效。
- 将表达式转换为内部表达式树。
- 循环访问节点,为基于表达式计算的结果集选择适当的节点。
与相应的 LINQ to XML 查询完成的工作相比,这需要执行非常多的工作。
除此之外,LINQ to XML还继承了父亲的延迟执行的优良传统,也能够提高性能。
父亲这么优秀,XmlDocument自然无法相比了。
所以,富二代和官二代起点就比你高,你如果不比他们多付出N倍的努力,你甚至连他们的起点都无法到达。
科普下延迟执行的知识:
延迟执行意味着表达式的计算延迟,直到真正需要它的实现值为止。 当必须操作大型数据集合,特别是在包含一系列链接的查询或操作的程序中操作时,延迟执行可以大大改善性能。 在最佳情况下,延迟执行只允许对源集合的单个循环访问。
LINQ 技术广泛应用了延迟执行,包括在核心 System.Linq 类的成员和不同 LINQ 命名空间中的扩展方法(如 System.Xml.Linq.Extensions)中使用。
除了上面的,其他的还有些他在成长过程中,自己提升的优点,比如:XName 和 XNamespace 对象是原子化的,如果这两个对象包含相同的名字,则它们会引用同一个对象。 也就是说当比较两个原子化名称是否相等时,只需确定这两个引用是否指向同一个对象,而不必进行很”耗费时间“的字符串比较,这个是有助于性能提升的。
尾声
虽然这不是拍电影,但是尾声还是必须的。
- 没有测试就没有发言权,并不是所有的”懒人技术“都是以牺牲性能为代价的。
- 虽然Linq to SQL的名声不大好,但是LINQ to XML却应该是实至名归。而且Linq to SQL的儿子EF正在挽回她的名声,如果你没用过,请不要说他不行,如果你用的不当,请也别说他不行。
- 懒人技术都是懒人发明的,但是往往就是这些懒人推动了技术的前进。
- 每一种技术和框架都是有使用场景的,如果你用错了场景,请不要说他不行。
- 合理把控性能,在大多数非苛刻场景,不到1毫秒甚至更多的差别,你完全不必要浪费1小时以上的精力,认真提高开发效率才是关键的。比如枚举类型的ToString()。
为什么LINQ to XML的性能要优于XmlDocument?的更多相关文章
- [原创]Linq to xml增删改查Linq 入门篇:分分钟带你遨游Linq to xml的世界
本文原始作者博客 http://www.cnblogs.com/toutou Linq 入门篇(一):分分钟带你遨游linq to xml的世界 本文原创来自博客园 请叫我头头哥的博客, 请尊重版权, ...
- C#学习之Linq to Xml
前言 我相信很多从事.NET开发的,在.NET 3.5之前操作XML会比较麻烦,但是在此之后出现了Linq to Xml,而今天的主人公就是Linq to Xml,废话不多说,直接进入主题. 题外:最 ...
- C#中的Linq to Xml详解
这篇文章主要介绍了C#中的Linq to Xml详解,本文给出转换步骤以及大量实例,讲解了生成xml.查询并修改xml.监听xml事件.处理xml流等内容,需要的朋友可以参考下 一.生成Xml 为了能 ...
- C# LINQ学习笔记五:LINQ to XML
本笔记摘抄自:https://www.cnblogs.com/yaozhenfa/p/CSharp_Linq_For_Xml.html,记录一下学习过程以备后续查用. 一.生成xml 1.1创建简单的 ...
- LINQ系列:LINQ to XML类
LINQ to XML由System.Xml.Linq namespace实现,该namespace包含处理XML时用到的所有类.在使用LINQ to XML时需要添加System.Xml.Linq. ...
- LINQ系列:LINQ to XML操作
LINQ to XML操作XML文件的方法,如创建XML文件.添加新的元素到XML文件中.修改XML文件中的元素.删除XML文件中的元素等. 1. 创建XML文件 string xmlFilePath ...
- LINQ系列:LINQ to XML查询
1. 读取XML文件 XDocument和XElement类都提供了导入XML文件的Load()方法,可以读取XML文件的内容,并转换为XDocument或XElement类的实例. 示例XML文件: ...
- Linq to Xml读取复杂xml(带命名空间)
前言:xml的操作方式有多种,但要论使用频繁程度,博主用得最多的还是Linq to xml的方式,觉得它使用起来很方便,就用那么几个方法就能完成简单xml的读写.之前做的一个项目有一个很变态的需求:C ...
- c#操作xml文件(XmlDocument,XmlTextReader,Linq To Xml)
主界面
随机推荐
- Eclipse的设置
1 Eclipse的工作空间和新建工程 1.1: 工作空间 * 其实就是我们写的源代码所在的目录 1.2: 创建工程(项目) * 右键/Package Explore 空白区/new /Java Pr ...
- org.apache.maven.archiver.mavenarchiver.getmanifest怎么解决
原因就是你的maven的配置文件不是最新的 1.help ->Install New Software -> add ->https://otto.takari.io/content ...
- 再探haproxy
一 设置haproxy输出log 1.1 调整配置文件 默认haproxy是不会输出log到文件的,这样很大程度在查询问题时会很不方便,haproxy是可以输出日志到文件的,配置文档类似于如下: ]# ...
- mac 命令行安装软件
第一步需要在mac上安装brew工具 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/mas ...
- FreeRTOS学习目录
1.关于实时操作系统的一些概念性问题 2.freeRTOS与裸机程序相比有什么区别?? 3.freeRTOSConfig.h文件对FreeRTOS进行系统配置 4.FreeRTOS的内存管理
- Ubuntu英文变为中文
Ubuntu英文变为中文 注:(我也是第一次变语言,写的有点乱,我把重点的用红字表示.) 1.点击这个软件更新. 2.只有点击了上面那一步,这里才会软件资源 Software Sources ...
- 【Solidity】学习(3)
函数 重定义 不支持重定义,会在编译时候报错 pragma solidity ^0.4.0; contract test { uint public a =100; function changeA ...
- sqoop错误集锦1
1.当时初学Sqoop的时候,mysql导入到hdfs导入命令执行以后,在hdfs上面没有找到对应的数据,今天根据这个bug,顺便解决这个问题吧,之前写的http://www.cnblogs.com/ ...
- PB开发境界 多个DW进行update
多个DW进行update //菜鸟代码dw_1.Update()dw_2.Update()初级代码IF dw_1.Update() = 1 And dw_2.Update() = 1 THEN ...
- PMS权限管理和鉴权过程
一.权限的管理基础知识 1.系统的权限机制分为:权限解析.权限分配.鉴权.动态添加权限 2.PermissionInfo : PackageParser.Permission中包含一个对应的Perm ...