Slow code in reading xml file

A

alessio211734

I trying to read a xml file and to fill a treeview with xml data.
The function code is used to fill a treeview but it's very very slow.

void PopulateXmlTreeView(XmlNode xnode,TreeNode tnode)
{
if (xnode.ChildNodes.Count>0)
{
//foreach (XmlNode xN in xnode.ChildNodes)
for (int i=0;i<xnode.ChildNodes.Count;i++)
{
XmlNode xN=xnode.ChildNodes;
TreeNode t=tnode.Nodes.Add(" ");
if (!(xN is System.Xml.XmlText))
t.Text+=xN.Name;
if (xN.Attributes!=null)
{
for (int j=0;j<xN.Attributes.Count;j++)
{
t.Text+=" ("+xN.Attributes.Item(j).Name;
t.Text+="= "+xN.Attributes.Item(j).Value+ ")";
//XmlAttributeCollection xN.Attributes.Count
//if (xN.Attributes!=null) t.Text=xN.Attributes.tex;
}
}
if (xN.Value!=null) t.Text+=" "+xN.Value;
PopulateXmlTreeView(xN,t);
}
}
}
 
S

sloan

You can start by using the StringBuilder class, and setting the t.Text
property ONCE, instead of concatenating it over and over.


using System.Text;


StringBuilder sb = new StringBuilder();
sb.Append(xN.Attributes.Item(j).Name + "=" +xN.Attributes.Item(j).Value+
")";

t.Text = sb.ToString();

Something along those lines.
 
A

alessio211734

I try to modify the function so:

for (int j=0;j<xN.Attributes.Count;j++)
{
StringBuilder sb = new StringBuilder();
sb.Append(xN.Attributes.Item(j).Name + "=" +xN.Attributes.Item
(j).Value+ ")" );
t.Text = sb.ToString();
}

no improvement, the code is again too slow.It's unusable.
 
I

Ignacio Machin ( .NET/ C# MVP )

I trying to read a xml file and to fill a treeview with xml data.
The function code is used to fill a treeview but it's very very slow.

void PopulateXmlTreeView(XmlNode xnode,TreeNode tnode)
{
   if (xnode.ChildNodes.Count>0)
   {
       //foreach (XmlNode xN in xnode.ChildNodes)
         for (int i=0;i<xnode.ChildNodes.Count;i++)
         {
             XmlNode xN=xnode.ChildNodes;
             TreeNode t=tnode.Nodes.Add(" ");
             if (!(xN is System.Xml.XmlText))
        t.Text+=xN.Name;
        if (xN.Attributes!=null)
        {
            for (int j=0;j<xN.Attributes.Count;j++)
            {
                 t.Text+=" ("+xN.Attributes.Item(j).Name;
                 t.Text+="= "+xN.Attributes.Item(j)..Value+ ")";
                 //XmlAttributeCollection xN.Attributes..Count
                 //if (xN.Attributes!=null) t.Text=xN.Attributes.tex;
            }
        }
        if (xN.Value!=null) t.Text+=" "+xN.Value;
        PopulateXmlTreeView(xN,t);
        }
    }
 }


Hi,

Well it's a recursive method, so it's will be slower than a non
recursive one.

you first should find where the slowness come from. If you have too
many attributes it can coe from the concatenation. It could also come
from the creation (and painting) of the tree.

Do this.

do not concatenate the attributes (getting rid of the second loop)
split the method in two methods, in the first you build the tree
struct, in the second you build you tree control from that tree.
 
A

Alberto Poblacion

alessio211734 said:
I try to modify the function so:

for (int j=0;j<xN.Attributes.Count;j++)
{
StringBuilder sb = new StringBuilder();
sb.Append(xN.Attributes.Item(j).Name + "=" +xN.Attributes.Item
(j).Value+ ")" );
t.Text = sb.ToString();
}

no improvement, the code is again too slow.It's unusable.

This is quite wrong. The idea is to create the StringBuilder OUTSIDE of
the loop, then use the loop to add text into the StringBuilder, and then,
after the loop is done, use the ToString method to convert back into a
string and assign it to the Text property. This avoids the repeated creation
and destruction of strings inside the loop; you won't see any improvement if
you merely replace the creation and destruction of strings with the creation
and destruction of stringbuilders. What you want to do is create the
StringBuilder only once (outside of the loop).
 
A

Anthony Jones

alessio211734 said:
I trying to read a xml file and to fill a treeview with xml data.
The function code is used to fill a treeview but it's very very slow.

void PopulateXmlTreeView(XmlNode xnode,TreeNode tnode)
{
if (xnode.ChildNodes.Count>0)
{
//foreach (XmlNode xN in xnode.ChildNodes)
for (int i=0;i<xnode.ChildNodes.Count;i++)
{
XmlNode xN=xnode.ChildNodes;
TreeNode t=tnode.Nodes.Add(" ");
if (!(xN is System.Xml.XmlText))
t.Text+=xN.Name;
if (xN.Attributes!=null)
{
for (int j=0;j<xN.Attributes.Count;j++)
{
t.Text+=" ("+xN.Attributes.Item(j).Name;
t.Text+="= "+xN.Attributes.Item(j).Value+ ")";
//XmlAttributeCollection xN.Attributes.Count
//if (xN.Attributes!=null) t.Text=xN.Attributes.tex;
}
}
if (xN.Value!=null) t.Text+=" "+xN.Value;
PopulateXmlTreeView(xN,t);
}
}
}


As others have suggested a string builder would be good to add, however its
not entirely convincing that would improve performance. It will reduce the
amount of memory the function will gobble up and that can affect perfromance
in extreme cases.

I would be most useful had you specified exactly where "very very slow" is
in terms of seconds and how many nodes in total you are adding to the
treeview.

Also is it the function itself thats slow or the time it takes to display
the control contents?
 
F

Frans Bouma [C# MVP]

alessio211734 said:
I trying to read a xml file and to fill a treeview with xml data.
The function code is used to fill a treeview but it's very very slow.

void PopulateXmlTreeView(XmlNode xnode,TreeNode tnode)
{
if (xnode.ChildNodes.Count>0)
{
//foreach (XmlNode xN in xnode.ChildNodes)
for (int i=0;i<xnode.ChildNodes.Count;i++)
{
XmlNode xN=xnode.ChildNodes;
TreeNode t=tnode.Nodes.Add(" ");
if (!(xN is System.Xml.XmlText))
t.Text+=xN.Name;
if (xN.Attributes!=null)
{
for (int j=0;j<xN.Attributes.Count;j++)
{
t.Text+=" ("+xN.Attributes.Item(j).Name;
t.Text+="= "+xN.Attributes.Item(j).Value+ ")";
//XmlAttributeCollection xN.Attributes.Count
//if (xN.Attributes!=null) t.Text=xN.Attributes.tex;
}
}
if (xN.Value!=null) t.Text+=" "+xN.Value;
PopulateXmlTreeView(xN,t);
}
}
}


1) call the treeview BeginUpdate() routine prior to calling this routine
2) add nodes with AddRange using an array in one go, so collect all new
nodes in the loop, then add them in 1 go then proceed inside the recursion
3) treeview controls tend to be slow with text changes, as this has to
be reflected in the visuable portion of the control, resizing has to
take place perhaps, it takes time. So be sure you produce the node's
text before you set it.
4) if you're processing a file, consider XmlReader instead of reading
the file in a DOM and traversing it.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top