Write strings directly to the Response buffer in ASP.NET efficiently. Every developer has had to write text with Response.Write() at some time. You want to improve Response.Write calls to be more logical and faster.
First, 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? [Improving .NET Application Performance and Scalability - MSDN]
Here I will assume you aren't using string appends and are already using Response.Write. The following code is the version I improved. It walks through Dictionary keys. It is the slow version. [C# - Dictionary Keys and Values - dotnetperls.com]
//
// A. Slow version (1568 ms)
//
foreach (KeyValuePair<string, int> 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. [C# - StringBuilder Secrets - dotnetperls.com]
//
// B. Slower version (1614 ms)
//
StringBuilder builder = new StringBuilder();
foreach (KeyValuePair<string, int> 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 (KeyValuePair<string, int> 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 (KeyValuePair<string, int> pair in _diskDictionary)
{
Response.Write(pair.Key);
Response.Write(':');
Response.Write(pair.Value.ToString());
Response.Write('\n');
}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.
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.
The fastest yet. 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 (KeyValuePair<string, int> pair in _diskDictionary)
{
r.Write(pair.Key);
r.Write(':');
r.Write(pair.Value.ToString());
r.Write('\n');
}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.
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.