Question

Hey guys - Got a a question.

we have got an XMLIDList helper which uses += ( :( )

What im looking for is the fastest possible way to do this. Its not been a problem before because the lists have been <10 items but we have added a new feature that can pass 15k items and as you can imagine.. its dog slow!

  public static string EncodeGuidListToXML(IList<Guid> elementsToEncode)
        {
            if (elementsToEncode == null || elementsToEncode.Count == 0)
                return String.Empty;

            string beginItemNode = BeginItemNode;
            string endItemNode = EndItemNode; 

            string xml = BeginRootNode;

            foreach (Guid item in elementsToEncode)
            {
                xml += beginItemNode + item.ToString().ToUpper() + endItemNode;
            }

            xml += EndRootNode;

            return xml;
        }

Thanks.

Was it helpful?

Solution

The best way is not to use string concatenation to start with, IMO. Use an XML API. Build an XDocument or an XmlDocument, and then convert that to a string at the end. While your logic is reasonably simple at the moment, as soon as you start needing values which need escaping or anything like that, you really don't want to be replicating all the logic of a real XML API... so use an existing one.

Here's an example of how you might rewrite your current method:

public static string EncodeGuidListToXml(IList<Guid> guids)
{
    if (elementsToEncode == null || elementsToEncode.Count == 0)
    {
        return "";
    }
    return new XDocument(
        new XElement("Root",
            guids.Select(guid => new XElement("Item", guid.ToString().ToUpper()))
        )).ToString();

}

If you really want to stick to building strings directly, StringBuilder is indeed the way to go.

OTHER TIPS

Using a StringBuilder should give you some performance improvements.

Because it "represents a mutable string of characters" it's much faster at string manipulation than concatenating strings directly as it doesn't have to copy the string each time

I ran a few test using your standard string method, the StringBuilder class method and a method utilising the XDocument and XElement classes. With short lists the StringBuilder class won but with larger lists the XML classes gave comparable times. The test code I used is below:

List<string> list;
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();

protected void Page_Load(object sender, EventArgs e)
{
    list = Enumerable.Range(0, 15000).Select(i => i.ToString()).ToList();
    UsingStrings();
    UsingStringBuilder();
    UsingXDocument();
}

private void UsingStrings()
{
    timer.Reset();
    timer.Start();
    string beginItemNode = "<Node>";
    string endItemNode = "</Node>";
    string xml = "<Root>";

    foreach (string item in list)
    {
        xml += beginItemNode + item + endItemNode;
    }

    xml += "</Root>";
    timer.Stop();
    Response.Write(string.Format("Strings time:{0}<br />", timer.Elapsed.Ticks));
}

private void UsingStringBuilder()
{
    timer.Reset();
    timer.Start();
    StringBuilder sb = new StringBuilder();
    sb.Append("<Root>");

    foreach (string item in list)
    {
        sb.AppendFormat("<Node>{0}</Node>", item);
    }

    sb.Append("</Root>");
    timer.Stop();
    Response.Write(string.Format("StringBuilder time:{0}<br />", timer.Elapsed.Ticks));
}

private void UsingXDocument()
{
    timer.Reset();
    timer.Start();
    XDocument xDoc = new XDocument();
    xDoc.Add(new XElement("Root"));
    foreach (var item in list)
    {
        XElement element = new XElement("Node", item);
        xDoc.Root.Add(element);
    }
    timer.Stop();
    Response.Write(string.Format("XDocument time:{0}<br />", timer.Elapsed.Ticks));
}

The above test gave the following results on my machine:

First run:
    Strings time:239750613
    StringBuilder time:55509
    XDocument time:61904
Second run:

    Strings time:289422753
    StringBuilder time:198595
    XDocument time:80032

If you want to display the XDocument XML as a string without formatting use:

string xml = xDoc.ToString(SaveOptions.DisableFormatting);

EDIT: I initially said XDocument was much faster but running the test a few times it seems that it is generally equivalent to the StringBuilder method although it appears to be more consistent whereas sometimes StringBuilder is faster, other times a fair bit slower. What is clear is that using strings is much slower in comparison.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top