XML数据读取方式性能比较(二)

黄舟
Freigeben: 2017-02-13 15:45:24
Original
1621 Leute haben es durchsucht

 话说上期概括了一下通用的xml读取方式,不过平时我们未必要用到XML源的全部数据,所以我又实验了一下读取部分数据的情况,比如根据标题的开头字母,出现位置进行筛选。

  对于三种随机读取方式来说,只要改变查询条件即可

XmlDocument: var nodeList = doc.DocumentElement.SelectNodes("item[substring(title,1,1)='M'][position() mod 10 = 0]");   XPathNavigator: var nodeList = nav.Select("/channel/item[substring(title,1,1)='M'][position() mod 10 = 0]");   Xml Linq: var nodelist = from node in xd.XPathSelectElements("/channel/item[substring(title,1,1)='M'][position() mod 10 = 0]")
Nach dem Login kopieren

  使用XPath,只要改一行代码。XPath也相当容易掌握,比SQL简单得多。可以参考W3C Shcool的语法介绍以及MSDN 针对XPath用户的LINQ To XML,一刻钟功夫你就能掌握其中奥秘。

  但对XmlReader方式,可没那么容易了,同样是读title以M开头,每十项取一项,想了半天,楞是没想出个优雅点的实现方式,只好如此:

代码

static List testXmlReader2() { var lstChannel = new List(); var reader = XmlReader.Create(xmlStream); int n = 0;Channel channel = null; Search: while (reader.Read()) { if (reader.Name == "item" && reader.NodeType == XmlNodeType.Element) { while (reader.Read()) { if (reader.Name == "item") break; if (reader.NodeType != XmlNodeType.Element) continue; switch (reader.Name) { case "title": var title = reader.ReadString(); if (title[0] != 'M') goto Search; n++; if (n % 10 != 0) goto Search; channel = new Channel(); channel.Title = title; break; case "link": channel.Link = reader.ReadString(); break; case "description": channel.Description = reader.ReadString(); break; case "content": channel.Content = reader.ReadString(); break; case "pubDate": channel.PubDate = reader.ReadString(); break; case "author": channel.Author = reader.ReadString(); break; case "category": channel.Category = reader.ReadString(); break; default: break; } lstChannel.Add(channel); } } } return lstChannel; }
Nach dem Login kopieren

  可以看到,代码结构发生了明显变化。为了作条件筛选,只得增加局部变量n,调整了实体类初始化,和加入集合语句的所在位置,甚至被迫用了遗忘多年的goto语句进行跳转(VB还好些)。业务逻辑渗进了代码细节的实现,用老赵的话说就是,一阵语法噪音的气息扑面而来。

  XmlTextReader的实现代理类XmlTextReaderImp(internal的,不能直接用),是个有上万行代码超级类,封装了大量直接对Xml字符级进行的操作。由于操作很接近底层,宏观上很难找到太好的代码优化方式。如果筛选条件,也就是业务逻辑再复杂一点,代码就会面目全非,可理解性可维护性如镜花水月。

  现在再来比较一下时间性能:

XmlDocment 26ms XPathNavigator 26ms XmlTextReader 20ms Xml Linq 28ms
Nach dem Login kopieren

  四种方式数据变得接近了,Document和Navigator消耗时间大幅下降,Reader方式下降不多,因为仍然要从头Read到底,减少的3ms可以认为由于减少了实体对象创建的开销。比较蹊跷的是Linq方式,居然没有变化,落在了最后。

  可以测试不同的查询条件,能看出这四种方式各有其性能极限,与Xml源的大小有关。比如对于前两种方式,就取决于XmlDocument.Load方法执行时间,在我本机上,Load这个Xml就需要23ms。Linq方式也不是雷打不动,如果处理的结果很少,执行时间会降1~2毫秒。

  Document和Navigator方式,性能会随数据量增大而明显下降。很容易猜到,是因为它们创建了许多无用对象的缘故。看一下各方式内存占用便知,在数据全部加载不筛选情况下,Document方式占用了23.3M左右的内存,而Navigator方式只要22.9M左右,这也解释了为什么Document方式性能下降更明显。Reader方式数据全加载,只要20.1M左右内存,除去程序启动本身的开销,较前两种内存占用不到一半。Linq方式在内存方面又有惊艳表现,只比Reader方式多占了不到500k。

  进一步的分析,得出了进一步的结论:除非有特别需要,慎用XmlTextReader,它对变化准备不足,容易出错。更加强烈推荐使用Linq方式,虽然某些情况下时间性能略低于Navigator方式,但优异的内存占用表现,奠定了它的首选地位。而且我相信,未来的Linq To XML,还会更加强大。

以上就是XML数据读取方式性能比较(二)的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!