ASP.NET Response.Write

Dot Net Perls
ASP.NET web programming framework

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.

Tip: Use Response.Write on each individual string or character. Don't concatenate anything before calling it if possible.

Examples

First, here we 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 and is considered the slow version.

Version A [C#]

//
// 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.

StringBuilder Secrets
Version B [C#]

//
// 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.

Version C [C#]

//
// 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.

Version D [C#]

//
// 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 here.

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.

Important update

After writing this article I discovered a better way to use Response.Write. I looked carefully at the Response type in IL Disassembler, 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.

Version E [C#]

//
// 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');
}
Note (please read)

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.

Blog article link

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...."

MSDN reference

Summary

The C# programming language

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.

ASP.NET Tutorials