【问题标题】:Why is this code for iterating over the DOM stupid slow?为什么这个迭代 DOM 的代码很慢?
【发布时间】:2011-05-07 12:12:20
【问题描述】:

这嵌套了大约 10 个函数,所以我只粘贴相关的部分:

这条线真的很慢:

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 上查找&lt;h3&gt; 节点。不应该有超过几千个节点,应该有吗?为什么这需要几分钟才能完成?


实际上,这里肯定存在一个错误,导致它返回的节点数量超过了应有的数量...I forked the question to address the issue

【问题讨论】:

  • 我无法给您任何具体的答案,但我可以为您指出 Joelonsoftware.com 上的一篇有趣的文章 在底部附近 Joel 谈到了使用 XML 处理大型数据集的性能影响. joelonsoftware.com/articles/fog0000000319.html
  • 只是一个猜测:尝试使用 List 而不是 IEnumerable / yield 并告诉我们这是否有帮助。出现问题的原因可能是编译器在使用 yield 时为索引器内部构建的状态机开销。
  • @Jon/Doc:你们都错了。这可能会稍微提高性能(我很欣赏这些建议......一旦找到错误,我将实施它)——但实际上在某处一个错误。它不止一次地遍历相同的节点。

标签: c# optimization html-agility-pack


【解决方案1】:
public IEnumerable<HtmlNode> Traverse()
{
    foreach (var node in _context)
    {
        yield return node;
        foreach (var child in Children().Traverse())
            yield return child;
    }
}

这段代码对我来说看起来很奇怪。 Children()_context 是独立的,因此在 _context 中为每个节点运行一次是没有意义的。

【讨论】:

  • 你是对的。我试图重用我已经拥有的功能。将接受关闭问题:)
猜你喜欢
  • 2010-10-19
  • 1970-01-01
  • 2011-03-27
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 2021-04-29
  • 2018-07-22
  • 2017-01-10
相关资源
最近更新 更多