2011-12-16 4 views
4

ノードを反復するためにXPathNavigatorを使用しているアプリケーションがあります。それは正常に動作しています。パフォーマンス上の理由から最適なのはどれですか:XPathとLinqとXmlとクエリを持つXPathNavigator?

しかし、私は

  1. 私はどのようなメリット(パフォーマンス、保守性)を取得します....私はXMLにLINQを使用している場合ことを知りたいですか?

  2. XPathでは、LINQ to Xmlパフォーマンスヒットは何ですか?

私はC#.net、VS 2010を使用していますが、私の.xmlは中間サイズです。

+0

あなたは測定と考えていますか? –

+0

@MitchWheatいいえ、コードをXPathNavigatorからLINQにxmlに変更する必要があります。だからそれをする前に私はそれを知りたい – Syed

+1

パフォーマンスを比較するときは、常に**シナリオに固有な**正確な*答えのためには1つのことしかありません...試してみてください。 –

答えて

3

まあ、XPathNavigatorは、一般にLinq to XMLクエリより高速です。しかし、いつも「しかし」があります。

Linq to XMLは、コードをより読みやすく保守しやすくします。 linqクエリを読み込んでXPathを解析する方が簡単です(少なくとも私にとって)。また、あなたのコードを正しいものにするのに役立つクエリを書くときには、intellisenseが得られます。 Linq to XMLは、必要な場合にデータを簡単に変更することも可能です。 XPathNavigatorは読み取り専用アクセスを提供します。

一方、実際に最高のパフォーマンスが必要な場合は、おそらくXPathNavigatorがおすすめです。現在のシナリオと達成しようとしている内容によって異なります。パフォーマンスが問題でない場合(XMLファイルはかなり小さいので、このファイルへのリクエストは多くはありません)、Linq to XMLで簡単に行えます。それ以外の場合はXPathNavigatorに近づけてください。

5

ここで既に述べた内容を追加するだけで、全体的なパフォーマンスは、問題のドキュメントで実際に行っていることに依存しているようです。これは、XElementとXPathNavigatorの間の解析パフォーマンスを比較する単純な実験的な実行に基づいて私が締結したものです。

あなたはこれらのノードを横断して、いくつかの属性値を読んで、ノードを選択している場合:

  • XElement.Elementが1.5の おおよそ倍にXElement.CreateNavigator.Selectよりも高速です。
  • XElement.CreateNavigator.Selectは、XPathNavigator.Selectよりも速い です。これは、およそ0.5倍です。
  • XPathNavigator.SelectはXElement.XPathSelectElementよりも、 で約0.5倍高速です。一方

、あなたもそれは少し面白い、各ノードの子の値を読んでいる場合:

  • XElement.Elementは0.5のおよそ倍にXElement.XPathSelectElementsよりも高速です。
  • XElement.XPathSelectElement 3.
  • XPathNavigator.Select 0.5のおおよそ倍XElement.CreateNavigator.Selectよりも速いのおおよそ倍XPathNavigator.Selectよりも高速です。

これらの結論は次のコードに基づいています:here

全体からダウンロードBooks.xmlを持つ

[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); 
    } 

、それはあなたを与える、XPathの拡張を除いて、XElementオブジェクトの解析APIのように見えますドキュメントが多少平坦であれば、最高のパフォーマンスを発揮します。あなたは

XElement.Element("book").Element("author").Element("firstname").SomethingElse() 

ような何かをする必要が深いネストされた構造を持っている場合は、XElement.XPathSelectElementは、パフォーマンスとコードの保守性との間で最良の妥協点を提供することができます。

+1

私はあなたの結果が読みやすさのためにパーセンテージの変化として表されない理由について興味がありますか? –

関連する問題