tags:

views:

308

answers:

3

I am trying to squeeze as much performance as i can from a custom HttpHandler that serves Xml content.

I' m wondering which is better for performance. Using the XmlTextWriter class or ad-hoc StringBuilder operations like:

StringBuilder sb = new StringBuilder("<?xml version="1.0" encoding="UTF-8" ?>");    
sb.AppendFormat("<element>{0}</element>", SOMEVALUE);

Does anyone have first hand experience?

A: 

Honestly until you really, really, really, really, really need to care about performance... don't.

Go with the more maintainable solution first, and only compromise when performance becomes a measurable issue. XmlTextWriter offers you the benefit of "Knowing" about how Xml is supposed to work. StringBuilder does not, and is therefore error prone. You don't want to spend a day tracking down a malformed node somewhere in your gnarly stringbuilder code.

Let the framework work for you.

Josh
Part of the xml serves some flash files, so we have send the ENTIRE content structure to the client on each request. So yes we really care about the performance.
This is micro-optimization though... what is the overall percentage of compute time compared to say... network latency? I am willing to bet that of all the places you could eek out some performance gains, this will net you the least ROI. Again, you need to do some actual measuring and optimize the entire pipeline, not just one tiny aspect of it.
Josh
True, we are at a point where we are deciding whether to write the xml files to disk and let the client/server caching take over. This would be the most efficient, but presents a whole new set of problems for us, so lets leave that for another question.
A: 

When SOMEVALUE has a & or < in it, this approach will get you into trouble. Use xml-aware classes to to generate xml. Have a read of HOWTO Avoid Being Called a Bozo When Producing XML.

AakashM
+4  A: 

As Josh said, this is a micro-optimization that you shouldn't even consider if you haven't proved its necessity. It's also really not difficult to test:

static void Main(string[] arguments)
{
    const int iterations = 100000;

    Stopwatch sw = new Stopwatch();
    sw.Start();
    string s = CreateUsingStringBuilder("content", iterations);
    sw.Stop();
    Console.WriteLine(String.Format("CreateUsingStringBuilder: {0}", sw.ElapsedMilliseconds));

    sw.Reset();
    sw.Start();
    s = CreateUsingXmlWriter("content", iterations);
    sw.Stop();
    Console.WriteLine(String.Format("CreateUsingXmlWriter: {0}", sw.ElapsedMilliseconds));

    Console.ReadKey();
}

private static string CreateUsingStringBuilder(string content, int iterations)
{
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < iterations; i++ )
        sb.AppendFormat("<element>{0}</element>", content);

    return sb.ToString();
}

private static string CreateUsingXmlWriter(string content, int iterations)
{
    StringBuilder sb = new StringBuilder();
    using (StringWriter sw = new StringWriter(sb))
    using (XmlWriter xw = XmlWriter.Create(sw))
    {
        xw.WriteStartElement("root");
        for (int i = 0; i < iterations; i++ )
            xw.WriteElementString("element", content);
        xw.WriteEndElement();
    }
    return sb.ToString();
}

Not only is the XmlWriter version consistently faster by a millisecond or two, it produces well-formed XML, which the other method doesn't.

But both methods are creating 100,000-element XML documents in about 60 milliseconds on my two-year-old laptop, an amount of time that dwindles into insignificance compared with the time it will take to push that much data over the network.

Robert Rossney
Awesome Job. I actually did this very same thing on my machine and was coming back here to post the results, but you beat me to the punch. My results are essentially the same as what you have found. +1
Josh