几种xml读取方法比较

这几天手上有个活,解析xml,众所周知xml的解析方法有:

  1. DOM
  2. SAX
  3. linq to xml
  4. plinq

测试用xml和生成代码

 1 static void CreateFile()
 2         {
 3             int N = 5000000;
 4             Random rand = new Random();
 5             using (var writer = new XmlTextWriter("VeryHugeXmlFile.xml",Encoding.UTF8))
 6             {
 7                 writer.Formatting = Formatting.Indented;
 8 
 9                 writer.WriteStartDocument();
10                 writer.WriteStartElement("Root");
11                 for (int count = 1; count <= N; count++)
12                 {
13                     writer.WriteStartElement("Person");
14                     writer.WriteElementString("Id",count.ToString());
15                     writer.WriteElementString("Name",rand.Next().ToString());
16                     writer.WriteElementString("Sex",rand.Next(0,2) == 0 ? "" : "");
17                     writer.WriteElementString("Age",rand.Next(1,101).ToString());
18                     writer.WriteEndElement();
19                 }
20                 writer.WriteEndElement();
21                 writer.WriteEndDocument();
22             }
23         }

之后会生成类似于下面的xml文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <Root>
 3   <Person>
 4     <Id>1</Id>
 5     <Name>897639886</Name>
 6     <Sex></Sex>
 7     <Age>80</Age>
 8   </Person>
 9   <Person>
10     <Id>2</Id>
11     <Name>2012162696</Name>
12     <Sex></Sex>
13     <Age>60</Age>
14   </Person>
15   <Person>

xml下载链接

测试代码

统计时间(只是粗略统计了一下运行时间)

1 static void Watch(Action<string> way,string file)
2         {
3             Stopwatch watch = new Stopwatch();
4 
5             watch.Start();
6             way(file);
7             watch.Stop();
8             Console.WriteLine(watch.ElapsedMilliseconds);
9         }

DOM

1 static void DomWay(string file)
2         {
3             XmlDocument doc = new XmlDocument();
4             doc.Load(file);
5 
6             Console.WriteLine(doc.SelectNodes(YOUR-XPATH-HERE).Count);
7 
8         }

SAX

 1 static void SaxWay(string file)
 2         {
 3             using (XmlTextReader reader = new XmlTextReader(file))
 4             {
 5                 int count = 0;
 6                 while (reader.Read())
 7                 {
 8                     if (reader.Name == "Person" && reader.NodeType == XmlNodeType.Element)
 9                     {
10                         reader.Read();
11                         reader.Read();
12 
13                         int? Id = null;
14                         int? name = null;
15                         string sex = null;
16                         int? age = null;
17 
18                         if (reader.Name == "Id")
19                         {
20                             Id = reader.ReadElementContentAsInt();
21                             reader.Read();
22                             name = reader.ReadElementContentAsInt();
23                             reader.Read();
24                             sex = reader.ReadElementContentAsstring();
25                             reader.Read();
26                             age = reader.ReadElementContentAsInt();
27                             reader.Read();
28                         }
29 
30                         if (reader.Name == "Person" && reader.NodeType == XmlNodeType.EndElement)
31                             reader.Read();
32 
33                         if (Id != null && name != null && sex != null && age != null)
34                         {
35                             if (在此设置自定义过滤条件)
36                                 count++;
37                         }
38                     }
39                 }
40 
41                 Console.WriteLine(count);
42             }
43         }

Linq to Xml

 1 static void LinqWay(string file)
 2         {
 3             var root = XElement.Load(file);
 4             var person = from p in root.Elements("Person") 
 7                          where 在此设置自定义过滤条件 
 8                          select id;
 9             Console.WriteLine(person.Count());
10         }

PLinq to Xml

 1 static void PLinqWay(string file)
 2         {
 3             var root = XElement.Load(file);
 4             var person = from p in root.Elements("Person").AsParallel() 
 7                          where 在此设置自定义过滤条件 
 8                          select id;
 9             Console.WriteLine(person.Count());
10         }

统计结果

在6核8G内存机器上,测试程序设置为x64和release模式,在xml查询结果相同的情况下取运行时间(ms),没有详细采集cpu和内存数据

两个模式,区别是加了一个素数的判断。

Id > 5000 && sex == "男"

&& age > 15 && age < 50

Id > 5000 && sex == "男"

&& age > 15 && age < 50 && IsPrimeInt(name)

sax 13857 40010
linq 27336 53760
plinq 24550 28846
dom 31737 0

由于dom模式本身xpath模式不支持嵌入函数,所以第二个测试没有采集结果。

小结

sax:速度优先,内存占用少,但是代码复杂度高。

linq:速度较sax慢,但是代码优雅,维护容易

plinq:同上,在非计算密集型模式中,不比linq和sax模式好多少。但是在计算密集下,后来居上

dom:速度落后,但是原生支持xpath,代码最优雅。

内存方面仅是肉眼观察了任务管理器,sax基本内存曲线为水平线,而linq&plinq在load的时候分配内存,可能其内部也是用了dom。

仓促行文,其中必有不实之处,往各位劳神指教。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇