几种xml读取方法比较

来源:互联网 发布:渲染软件哪些 编辑:程序博客网 时间:2024/09/21 09:02

这几天手上有个活,解析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)

sax1385740010linq2733653760plinq2455028846dom317370

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

 

小结

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

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

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

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

 

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

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

0 0
原创粉丝点击