@Dawkins
100 runs is too few, you need to run about 10000 times several times and repeat it and then take the average of that to get a reliable result. The margin of error is to big in your example, but it's the right way to go.
Here's what i did:
var results1 = new List<long>();
var results2 = new List<long>();
for (int j = 0; j < 100; j++)
{
var sp = new System.Diagnostics.Stopwatch();
// With HttpContext.Current:
sp.Start();
for (int i = 0; i < 10000; i++)
{
HttpContext.Current.Response.Output.Write(i);
}
sp.Stop();
results1.Add(sp.ElapsedTicks);
// Without:
TextWriter output2 = HttpContext.Current.Response.Output;
sp.Reset();
sp.Start();
for (int i = 0; i < 10000; i++)
{
output2.Write(i);
}
sp.Stop();
HttpContext.Current.Response.Clear();
results2.Add(sp.ElapsedTicks);
}
results1.Sort();
results2.Sort();
HttpContext.Current.Response.Write(string.Format("HttpContext.Current={0:0.000}ms, Local variable={1:0.000}ms, R={2:0.0%}<br/>", results1[results1.Count / 2] / (double)TimeSpan.TicksPerMillisecond, results2[results2.Count / 2] / (double)TimeSpan.TicksPerMillisecond, (double)results1[results1.Count / 2] / (double)results2[results2.Count / 2]));
Your result show that there's a 18% performance difference, which shows that it's more expensive but it off by 8%.
I re-ran the numbers several times and came up with a 10% difference with a error margin of less then 1%.
It stablaizes around:
HttpContext.Current=0,536ms, Local variable=0,486ms, R=110,2%
Anyway, HttpContext.Current to pose a significant performance problem you'll need to call it way more than 10000 per request (the cost is largely made up by the Response.Write calls). And that's likely not going to happen.