我有一個應用程序,使用XPathNavigator來迭代節點。它工作正常。哪個性能最好:帶XPath的XPathNavigator vs帶查詢的Linq to Xml?
但我想知道,如果我使用LINQ到XML ....
什麼好處(性能,可維護性),我會得到什麼?
用XPath,LINQ to Xml是什麼性能打擊?
我使用C#.net,VS 2010和我的.xml是中等大小。
我有一個應用程序,使用XPathNavigator來迭代節點。它工作正常。哪個性能最好:帶XPath的XPathNavigator vs帶查詢的Linq to Xml?
但我想知道,如果我使用LINQ到XML ....
什麼好處(性能,可維護性),我會得到什麼?
用XPath,LINQ to Xml是什麼性能打擊?
我使用C#.net,VS 2010和我的.xml是中等大小。
那麼,XPathNavigator
通常會快於Linq to XML
查詢。但總是有'但'。
Linq to XML
肯定會讓你的代碼更具可讀性和可維護性。閱讀linq查詢然後分析XPath會更容易(至少對我來說)。另外 - 在寫查詢時你會得到智能感知,這將有助於使你的代碼正確。 Linq to XML
也爲您提供了輕鬆修改數據的可能性,如果這是您的需要。 XPathNavigator
爲您提供只讀訪問權限。
另一方面,如果您確實需要頂級性能,XPathNavigator
可能是最佳選擇。它僅取決於您當前的場景以及您想要完成的內容。如果性能不是問題(XML文件相當小,您不會向這個文件發出很多請求等),您可以輕鬆地使用Linq to XML
。否則堅持接近XPathNavigator
。
爲了增加已經在此處陳述的內容,整體表現似乎取決於您對相關文檔的實際操作。這是我基於一個簡單的實驗運行得出的結論,比較了XElement與XPathNavigator之間的解析性能。
如果您選擇的節點,遍歷這些節點和閱讀一些屬性值:
在另一方面,如果你還讀每個節點的孩子們的價值就有點耐人尋味:
這些結論是基於以下代碼:
[Test]
public void CompareXPathNavigatorToXPathSelectElement()
{
var max = 100000;
Stopwatch watch = new Stopwatch();
watch.Start();
bool parseChildNodeValues = true;
ParseUsingXPathNavigatorSelect(max, watch, parseChildNodeValues);
ParseUsingXElementElements(watch, max, parseChildNodeValues);
ParseUsingXElementXPathSelect(watch, max, parseChildNodeValues);
ParseUsingXPathNavigatorFromXElement(watch, max, parseChildNodeValues);
}
private static void ParseUsingXPathNavigatorSelect(int max, Stopwatch watch, bool parseChildNodeValues)
{
var document = new XPathDocument(@"data\books.xml");
var navigator = document.CreateNavigator();
for (var i = 0; i < max; i++)
{
var books = navigator.Select("/catalog/book");
while (books.MoveNext())
{
var location = books.Current;
var book = new Book();
book.Id = location.GetAttribute("id", "");
if (!parseChildNodeValues) continue;
book.Title = location.SelectSingleNode("title").Value;
book.Genre = location.SelectSingleNode("genre").Value;
book.Price = location.SelectSingleNode("price").Value;
book.PublishDate = location.SelectSingleNode("publish_date").Value;
book.Author = location.SelectSingleNode("author").Value;
}
}
watch.Stop();
Console.WriteLine("Time using XPathNavigator.Select = " + watch.ElapsedMilliseconds);
}
private static void ParseUsingXElementElements(Stopwatch watch, int max, bool parseChildNodeValues)
{
watch.Restart();
var element = XElement.Load(@"data\books.xml");
for (var i = 0; i < max; i++)
{
var books = element.Elements("book");
foreach (var xElement in books)
{
var book = new Book();
book.Id = xElement.Attribute("id").Value;
if (!parseChildNodeValues) continue;
book.Title = xElement.Element("title").Value;
book.Genre = xElement.Element("genre").Value;
book.Price = xElement.Element("price").Value;
book.PublishDate = xElement.Element("publish_date").Value;
book.Author = xElement.Element("author").Value;
}
}
watch.Stop();
Console.WriteLine("Time using XElement.Elements = " + watch.ElapsedMilliseconds);
}
private static void ParseUsingXElementXPathSelect(Stopwatch watch, int max, bool parseChildNodeValues)
{
XElement element;
watch.Restart();
element = XElement.Load(@"data\books.xml");
for (var i = 0; i < max; i++)
{
var books = element.XPathSelectElements("book");
foreach (var xElement in books)
{
var book = new Book();
book.Id = xElement.Attribute("id").Value;
if (!parseChildNodeValues) continue;
book.Title = xElement.Element("title").Value;
book.Genre = xElement.Element("genre").Value;
book.Price = xElement.Element("price").Value;
book.PublishDate = xElement.Element("publish_date").Value;
book.Author = xElement.Element("author").Value;
}
}
watch.Stop();
Console.WriteLine("Time using XElement.XpathSelectElement = " + watch.ElapsedMilliseconds);
}
private static void ParseUsingXPathNavigatorFromXElement(Stopwatch watch, int max, bool parseChildNodeValues)
{
XElement element;
watch.Restart();
element = XElement.Load(@"data\books.xml");
for (var i = 0; i < max; i++)
{
// now we can use an XPath expression
var books = element.CreateNavigator().Select("book");
while (books.MoveNext())
{
var location = books.Current;
var book = new Book();
book.Id = location.GetAttribute("id", "");
if (!parseChildNodeValues) continue;
book.Title = location.SelectSingleNode("title").Value;
book.Genre = location.SelectSingleNode("genre").Value;
book.Price = location.SelectSingleNode("price").Value;
book.PublishDate = location.SelectSingleNode("publish_date").Value;
book.Author = location.SelectSingleNode("author").Value;
}
}
watch.Stop();
Console.WriteLine("Time using XElement.Createnavigator.Select = " + watch.ElapsedMilliseconds);
}
用的books.xml從here
總體下載,它看起來像的XElement解析API,不包括XPath的擴展,使您最好的性能,同時也更容易使用,如果你的文檔有點平淡。如果你有,你必須做一些像
XElement.Element("book").Element("author").Element("firstname").SomethingElse()
深嵌套結構則XElement.XPathSelectElement可以提供性能和代碼的可維護性之間的最佳平衡。
你有沒有考慮測量? – 2011-12-16 06:08:27
@MitchWheat不,我需要將我的代碼從XPathNavigator更改爲LINQ到xml。所以在做這件事之前,我想知道它 – Syed 2011-12-16 06:11:52