Apropos, in der letzten Ausgabe wurde die allgemeine XML-Lesemethode zusammengefasst, aber normalerweise verwenden wir nicht unbedingt alle Daten der XML-Quelle, also habe ich mit dem Lesen einiger Daten experimentiert, wie zum Beispiel der Position basierend auf dem Anfangsbuchstaben des Titels.
Für die drei Zufallslesemethoden müssen Sie nur die Abfragebedingungen ändern
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]")
Mit XPath müssen Sie nur eine Codezeile ändern. XPath ist außerdem relativ einfach zu beherrschen, viel einfacher als SQL. Sie können sich die Syntaxeinführung von W3C Shcool und LINQ To XML für XPath-Benutzer von MSDN ansehen und die Geheimnisse in einer Viertelstunde beherrschen.
Aber für die XmlReader-Methode ist es nicht so einfach. Sie liest auch den Titel, der mit M beginnt, und wählt nach langem Nachdenken keinen aus elegante Implementierung, also musste ich das tun:
Code
static List<Channel> testXmlReader2() { var lstChannel = new List<Channel>(); 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; }
Wie Sie sehen können, hat sich die Codestruktur erheblich geändert. Um eine bedingte Filterung durchzuführen, musste ich die lokale Variable n hinzufügen, die Initialisierung der Entitätsklasse anpassen und den Speicherort der Sammlungsanweisung hinzufügen. Ich war sogar gezwungen, die goto-Anweisung zu verwenden, die ich viele Jahre lang vergessen hatte springen (VB ist besser). Geschäftslogik dringt in die Implementierung von Codedetails ein. In Lao Zhaos Worten trifft ein Ausbruch grammatikalischer Geräusche auf das Gesicht.
Da die Operation sehr nahe an der untersten Ebene liegt, ist es schwierig, eine gute Methode zur Codeoptimierung auf Makroebene zu finden. Wenn die Filterbedingungen, also die Geschäftslogik, komplizierter sind, ist der Code völlig anders und die Verständlichkeit und Wartbarkeit ist wie ein Spiegel.
Vergleichen wir nun die Zeitleistung:
XmlDocment 26ms XPathNavigator 26ms XmlTextReader 20ms Xml Linq 28ms
Die Daten in den vier Methoden liegen nahe beieinander, der Zeitverbrauch von Document und Navigator ist erheblich gesunken und die Reader-Methode ist nicht gesunken viel, da es immer noch von Anfang an gelesen werden muss. Letztendlich kann die Reduzierung um 3 ms auf die Reduzierung des Aufwands für die Erstellung von Entitätsobjekten zurückgeführt werden. Noch seltsamer ist, dass sich die Linq-Methode nicht geändert hat und am Ende versagt hat.
Sie können verschiedene Abfragebedingungen testen. Es ist ersichtlich, dass jede dieser vier Methoden ihre eigene Leistungsgrenze hat, die mit der Größe der XML-Quelle zusammenhängt. Bei den ersten beiden Methoden hängt es beispielsweise von der Ausführungszeit der XmlDocument.Load-Methode ab. Auf meinem Computer dauert das Laden der XML-Datei 23 ms. Die Linq-Methode ist nicht unzerbrechlich. Wenn nur wenige Ergebnisse verarbeitet werden müssen, verkürzt sich die Ausführungszeit um 1 bis 2 Millisekunden.
Im Dokument- und Navigatormodus nimmt die Leistung mit zunehmender Datenmenge erheblich ab. Es ist leicht zu vermuten, dass das daran liegt, dass sie eine Menge nutzloser Objekte erzeugen. Wenn wir uns die Speichernutzung jeder Methode ansehen, können wir sehen, dass die Document-Methode etwa 23,3 MB Speicher beansprucht, während die Navigator-Methode nur etwa 22,9 MB beansprucht. Dies erklärt auch, warum die Leistung der Document-Methode nimmt deutlicher ab. Der Lesemodus ist vollständig mit Daten geladen und benötigt nur etwa 20,1 MB Speicher. Ohne den Overhead des Programmstarts selbst nimmt er im Vergleich zu den beiden vorherigen Methoden weniger als die Hälfte des Speichers ein. Die Linq-Methode bietet eine weitere erstaunliche Leistung in Bezug auf den Speicher und benötigt weniger als 500.000 mehr als die Reader-Methode.
Eine weitere Analyse führte zu einer weiteren Schlussfolgerung: Verwenden Sie XmlTextReader mit Vorsicht, es sei denn, es besteht ein besonderer Bedarf. Es ist schlecht auf Änderungen vorbereitet und fehleranfällig. Es wird dringend empfohlen, die Linq-Methode zu verwenden. Obwohl die Zeitleistung in einigen Fällen etwas geringer ist als die der Navigator-Methode, hat sich ihre hervorragende Speichernutzungsleistung als erste Wahl etabliert. Und ich glaube, dass Linq To XML in Zukunft noch leistungsfähiger sein wird.
Das Obige ist der Leistungsvergleich der XML-Datenlesemethoden (2). Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!