2010-11-09 101 views
1

這是嵌套約10種功能深,所以我就粘貼相關位:爲什麼這個迭代DOM愚蠢的代碼很慢?

這一行實在是太慢了:

var nodes = Filter_Chunk(Traverse(), chunks.First()); 

具體而言,該塊內Filter_Chunk(雙關語不打算):

private static IEnumerable<HtmlNode> Filter_Chunk(IEnumerable<HtmlNode> nodes, string selectorChunk) 
{ 
    // ... 
    string tagName = selectorChunk; 
    foreach (var node in nodes) 
     if (node.Name == tagName) 
      yield return node; 

沒有什麼在那裏太複雜了......所以我想它一定是在Traverse()右節點的數量之多?

public IEnumerable<HtmlNode> Traverse() 
{ 
    foreach (var node in _context) 
    { 
     yield return node; 
     foreach (var child in Children().Traverse()) 
      yield return child; 
    } 
} 

public SharpQuery Children() 
{ 
    return new SharpQuery(_context.SelectMany(n => n.ChildNodes).Where(n => n.NodeType == HtmlNodeType.Element), this); 
} 

我試過stackoverflow.com發現<h3>節點。不應該有超過幾千個節點,應該在那裏嗎?爲什麼這需要很多分鐘才能完成?


其實,有肯定在這裏的某個地方一個錯誤,導致它比它應返回多個節點... I forked the question to address the issue

+1

[C#在樹中嵌套良率的性能]可能的重複(http://stackoverflow.com/questions/1043050/c-performance-of-nested-yield-in-a-tree) – 2010-11-09 20:49:07

+0

我不能給你任何特定的答案,但是我可以給你一個關於Joelonsoftware.com的有趣的文章。在底部附近Joel談論了在大型數據集中使用XML的性能問題。 http://www.joelonsoftware.com/articles/fog0000000319.html – 2010-11-09 20:51:15

+0

只是一個猜測:嘗試使用列表而不是IEnumerable/yield並告訴我們是否有幫助。您的問題的原因可能是編譯器在使用yield時在內部爲索引器構建的狀態機的開銷。 – 2010-11-09 21:01:08

回答

2
public IEnumerable<HtmlNode> Traverse() 
{ 
    foreach (var node in _context) 
    { 
     yield return node; 
     foreach (var child in Children().Traverse()) 
      yield return child; 
    } 
} 

這段代碼看起來很奇怪我。 Children()對於_context是獨立的,所以對_context中的每個節點運行一次兒童是沒有意義的。

+0

你說得對。我試圖重新使用我已有的功能。將接受關閉問題:) – mpen 2010-11-09 22:49:52