几种xml读取方法比较
背景
這幾天手上有個(gè)活,解析xml,眾所周知xml的解析方法有:
測(cè)試用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 }之后會(huì)生成類(lèi)似于下面的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下載鏈接
測(cè)試代碼
統(tǒng)計(jì)時(shí)間(只是粗略統(tǒng)計(jì)了一下運(yùn)行時(shí)間)
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 (在此設(shè)置自定義過(guò)濾條件) 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 在此設(shè)置自定義過(guò)濾條件
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 在此設(shè)置自定義過(guò)濾條件
8 select id; 9 Console.WriteLine(person.Count()); 10 }
?統(tǒng)計(jì)結(jié)果
?在6核8G內(nèi)存機(jī)器上,測(cè)試程序設(shè)置為x64和release模式,在xml查詢(xún)結(jié)果相同的情況下取運(yùn)行時(shí)間(ms),沒(méi)有詳細(xì)采集cpu和內(nèi)存數(shù)據(jù)
兩個(gè)模式,區(qū)別是加了一個(gè)素?cái)?shù)的判斷。
?
| ? | 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模式不支持嵌入函數(shù),所以第二個(gè)測(cè)試沒(méi)有采集結(jié)果。
?
小結(jié)
sax:速度優(yōu)先,內(nèi)存占用少,但是代碼復(fù)雜度高。
linq:速度較sax慢,但是代碼優(yōu)雅,維護(hù)容易
plinq:同上,在非計(jì)算密集型模式中,不比linq和sax模式好多少。但是在計(jì)算密集下,后來(lái)居上
dom:速度落后,但是原生支持xpath,代碼最優(yōu)雅。
?
內(nèi)存方面僅是肉眼觀察了任務(wù)管理器,sax基本內(nèi)存曲線(xiàn)為水平線(xiàn),而linq&plinq在load的時(shí)候分配內(nèi)存,可能其內(nèi)部也是用了dom。
倉(cāng)促行文,其中必有不實(shí)之處,往各位勞神指教。
?
轉(zhuǎn)載于:https://www.cnblogs.com/diggingdeeply/p/access_xml_file_ways.html
總結(jié)
以上是生活随笔為你收集整理的几种xml读取方法比较的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 求数组中的最大数,最小数。
- 下一篇: [实变函数]4.2 Egrov 定理