XmlNode.ChildNodes[index] bad performance

Hello,

I'm using XmlNode.ChildNodes[index] function to access a node by index, and it causes a performance problem.

Is there a better way to access a node by index

Thanks,




Answer this question

XmlNode.ChildNodes[index] bad performance

  • Bollwerk

    OK, I'll stay with my current solution and hold an extra array for access by index

    too bad there is no built-in option in the interface



  • M_J

    I'm using .net framework verion 2.0

    and yes, what I need is all types of child nodes, about 10,000 nodes

    if I do a foreach loop on the nodes it is much faster than a for loop, with access by index.

    my current solution is to do one foreach loop, initialize an array of nodes, and then when I need a node by index I use the array.

    I haven't found a different way to do it...



  • Zac Boyles

    Can you provide some details such as which .NET version you are using, how many child nodes there are when you get performance problems

    Also to think about better ways it might help us what kind of nodes you are looking for If you are really interested in all kind of child nodes based on the index then there are probably no changes possible. On the other hand if you are for instance only looking for element child nodes then using XPath and e.g. SelectSingleNode might provide an alternative way where you could then check whether it performance better in your case.



  • hrubesh

    Hi!

    this problem is because child nodes are internally stored as a list rather than an array.

    So internally, each time you use ChildNodes it runs the following code:

    public virtual XmlNodeList get_ChildNodes()
    {
       return new XmlChildNodes(this);
    }
    
    You can see, it seems to create a complete array of *all* child nodes everytime to use the property ChildNodes, and then let you access this array.
    Of course this is horrobly slow. if you have code like:
    for( int i = 0;....)
       node.ChildNodes[ i]
    A considerable performance increase should be:
    XmlNodeList childs = node.ChildNodes
    for( int i = 0;.... )
       childs[ i]
    However, even this will always be slower than running through the linked list of nodes using an iterator.
    HTH, Alex


  • rravech

    Oooooops, I started to doubt on what I wrote myself an digged a little deeper :)

    So what I wrote above was slighty wrong. It does not create an array each time (that would be really completly...).

    Yes, it creates a new object all the time you use ChildNodes. So suggestion to take it out of loops avoids creating 10k objects in your case. Should help already.

    The major problem in your case however, stays the lists which are bad to access by index by design.

    This is what happens when you access the list by index:

    public override XmlNode Item(int i)
    {
       if (i >= 0)
       {
          XmlNode node1 = this.container.FirstChild;
          while (node1 != null)
          {
             if (i == 0)
             {
                return node1;
             }
             node1 = node1.NextSibling;
             i--;
          }
       }
       return null;
    }
    

    An iterator in contrast simply proceeds from one sibling to another instead of running through the whole lis looking for the requeste index.

    Regards, Alex



  • XmlNode.ChildNodes[index] bad performance