ASP.NET Response.Write Test

You want to write strings directly to the Response buffer in ASP.NET. Every developer has had to write text with Response.Write at some time. Here we improve Response.Write calls to be clearer and faster, and benchmark the results, using the C# programming language.

=== Response.Write method in ASP.NET performance ===
    20000 iterations.                               

Method A: 1568 ms
          Concats string parameter of Response.Write.

Method B: 1614 ms
          Appends data to StringBuilder than writes that.

Method C: 1474 ms
          Writes each part of data individually to Response.

Method D: 1318 ms
          Same as Method C except...
          Uses UNIX newline instead of Windows newline.

Method E: 1200 ms
          Stores HttpResponse as local variable.
          Only accesses Response property once.
          Is an estimate; was taken on different scale.

Using Response.Write

First, here we will assume you aren't using string appends and are already using Response.Write. The following code is the version the author improved. It walks through Dictionary keys and is considered the slow version.

//
// A. Slow version (1568 ms)
//
foreach (var pair in _diskDictionary)
{
    Response.Write(pair.Key + ":" + pair.Value.ToString() + Environment.NewLine);
}

Even slower version. I tried eliminating the repeated Write calls and simply use a temporary StringBuilder. I varied the capacity of the StringBuilder, but this next code is as good as I got it.

See StringBuilder Secrets.

//
// B. Slower version (1614 ms)
// 
StringBuilder builder = new StringBuilder();
foreach (var pair in _diskDictionary)
{
    builder.Append(pair.Key).Append(":").Append(pair.Value.ToString()).AppendLine();
}
Response.Write(builder.ToString());

Faster version. What I changed here: I split up the Response.Write calls to send one argument at a time and not concatenate anything beforehand. This was a substantial speedup.

//
// C. Faster version (1474 ms)
//
foreach (var pair in _diskDictionary)
{
    Response.Write(pair.Key);
    Response.Write(':');
    Response.Write(pair.Value.ToString());
    Response.Write(Environment.NewLine);
}

Fastest version. The final improvement in this code I made was change the newline to be a simple '\n' character. This changes the output but in this case it didn't matter.

//
// D. Fastest version (1318 ms)
//
foreach (var pair in _diskDictionary)
{
    Response.Write(pair.Key);
    Response.Write(':');
    Response.Write(pair.Value.ToString());
    Response.Write('\n');
}

Benchmark details

I ran the above code fragments 20,000 times each with a dictionary of 180 key/value pairs. The output file was 4 KB and I used Response.Clear() to erase the buffer each time. The figures from the experiment are available at the top of this article.

Important update

After writing this article I discovered a better way to use Response.Write. I looked carefully at the Response object in Reflector, and it is accessed through a property. Properties are slower than local instances. We can cache the Response object locally, and performance improves by nearly 10% in my benchmark. The numbers I measured here were 748 before and 671 after, on a smaller data set.

//
// E. Faster than fastest version
//
HttpResponse r = Response;
foreach (var pair in _diskDictionary)
{
    r.Write(pair.Key);
    r.Write(':');
    r.Write(pair.Value.ToString());
    r.Write('\n');
}

Notes

We see how ASP.NET works with the Response buffer. The best approach is to simply pass in each string one at a time. This is faster, uses less memory, and even simpler to read. I noted a performance degradation when not calling ToString on the int values above. I don't really know why. Response.Write may have slower code for ints.

More resources. Alik Levin has an interesting post with how Response.Write() is faster than alternative methods. This aligns with the Microsoft guidelines linked to above.

Visit blogs.msdn.com.

Microsoft guidelines. Finally, let's look at the Improving ASP.NET Performance document from Microsoft. It tells us what we need to know, but here I provide benchmarks and examples. What do Microsoft's guidelines tell us? Avoid strings. This is pretty obvious, but you don't want to use simple strings to build up output. This would involve the + operator.

Why is Response.Write fast? "Response.Write internally appends strings to a reusable buffer so that it does not suffer the performance overhead of allocating memory...."

Visit msdn.microsoft.com.

Summary

Here we looked at usages of the Response.Write method for appending strings to the Response buffer in the ASP.NET framework and the C# programming language. You can call Response.Write with individual string arguments for the clearest and fastest code. There's a good and a bad way to use Response.Write(), and avoiding string + operations is the good way.

See ASP.NET Tutorials.

© 2007-2010 Sam Allen. All rights reserved.

Dot Net Perls  Sam Allen