• 几种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。

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

  • 相关阅读:
    [UE4]Image
    [UE4]CheckBox
    [UE4]Button
    [UE4]Border
    [UE4]RichTextBlock
    [UE4]Text Box
    [UE4]字体材质
    [UE4]Retainer Box
    [UE4]Invalidation Box
    [UE4]Dynamic Entry Box
  • 原文地址:https://www.cnblogs.com/diggingdeeply/p/access_xml_file_ways.html
Copyright © 2020-2023  润新知