我有一個150 MB的XML文件,在我的項目中用作數據庫。目前,我正在使用XmlReader
從中讀取內容。我想知道在這種情況下最好使用XmlReader
或LINQ to XML。性能:XmlReader或LINQ到XML
請注意,我正在搜索此XML中的項目並顯示搜索結果,因此可能需要很長時間或僅需一小會兒。
我有一個150 MB的XML文件,在我的項目中用作數據庫。目前,我正在使用XmlReader
從中讀取內容。我想知道在這種情況下最好使用XmlReader
或LINQ to XML。性能:XmlReader或LINQ到XML
請注意,我正在搜索此XML中的項目並顯示搜索結果,因此可能需要很長時間或僅需一小會兒。
如果您希望性能使用XMLReader。它不會讀取整個文件並在內存中構建DOM樹。而是從磁盤讀取文件,並將其返回到找到的每個節點。
通過快速的谷歌搜索,我發現了XMLReader,LinqToXML和XDocument.Load的性能比較。
寫了幾個基準測試,以確定情況到底是什麼給你,並把它從那裏... Linq2XML引入了很大的靈活性...
我會親自看看使用LINQ to XML利用微軟的幫助文件中列出的流媒體技術: http://msdn.microsoft.com/en-us/library/system.xml.linq.xstreamingelement.aspx#Y1392
這裏有一個快速的基準測試由一個200MB的XML文件中讀取一個簡單的過濾器:
var xmlFilename = "test.xml";
//create test xml file
var initMemoryUsage = GC.GetTotalMemory(true);
var timer = System.Diagnostics.Stopwatch.StartNew();
var rand = new Random();
var testDoc = new XStreamingElement("root", //in order to stream xml output XStreamingElement needs to be used for all parent elements of collection so no XDocument
Enumerable.Range(1, 10000000).Select(idx => new XElement("child", new XAttribute("id", rand.Next(0, 1000))))
);
testDoc.Save(xmlFilename);
var outStat = String.Format("{0:f2} sec {1:n0} kb //linq to xml ouput streamed", timer.Elapsed.TotalSeconds, (GC.GetTotalMemory(false) - initMemoryUsage)/1024);
//linq to xml not streamed
initMemoryUsage = GC.GetTotalMemory(true);
timer.Restart();
var col1 = XDocument.Load(xmlFilename).Root.Elements("child").Where(e => (int)e.Attribute("id") < 10).Select(e => (int)e.Attribute("id")).ToArray();
var stat1 = String.Format("{0:f2} sec {1:n0} kb //linq to xml input not streamed", timer.Elapsed.TotalSeconds, (GC.GetTotalMemory(false) - initMemoryUsage)/1024);
//xmlreader
initMemoryUsage = GC.GetTotalMemory(true);
timer.Restart();
var col2 = new List<int>();
using (var reader = new XmlTextReader(xmlFilename))
{
while (reader.ReadToFollowing("child"))
{
reader.MoveToAttribute("id");
int value = Convert.ToInt32(reader.Value);
if (value < 10)
res2.Add(value);
}
}
var stat2 = String.Format("{0:f2} sec {1:n0} kb //xmlreader", timer.Elapsed.TotalSeconds, (GC.GetTotalMemory(false) - initMemoryUsage)/1024);
//linq to xml streamed
initMemoryUsage = GC.GetTotalMemory(true);
timer.Restart();
var col3 = StreamElements(xmlFilename, "child").Where(e => (int)e.Attribute("id") < 10).Select(e => (int)e.Attribute("id")).ToArray();
var stat3 = String.Format("{0:f2} sec {1:n0} kb //linq to xml input streamed", timer.Elapsed.TotalSeconds, (GC.GetTotalMemory(false) - initMemoryUsage)/1024);
//util method
public static IEnumerable<XElement> StreamElements(string filename, string elementName)
{
using (var reader = XmlTextReader.Create(filename))
{
while (reader.Name == elementName || reader.ReadToFollowing(elementName))
yield return (XElement)XElement.ReadFrom(reader);
}
}
而這裏的處理時間和內存使用我的機器上:
11.49 sec 225 kb // linq to xml ouput streamed
17.36 sec 782,312 kb // linq to xml input not streamed
6.52 sec 1,825 kb // xmlreader
11.74 sec 2,238 kb // linq to xml input streamed
我覺得你在這裏誤用XML。不要將它用作數據庫。 150 MB? :o相關:http://stackoverflow.com/questions/1154499/linq-to-xml-vs-xmlreader – nawfal 2015-08-20 06:11:54