.Net Reflection and Performance
I ran into an interesting post today on the ASP. Net NewsGroup regarding Reflection. Somebody mentioned using Reflection inside of an ASP.Net page and was wondering whether this would be a big performance drain on his application. One response later the original poster walks away thinking that a single call to Reflection is going to completely kill the performance of his Web application.
This isn’t the first time I've heard concerns over this – there seems to be a lot of misconception of how Reflection works and what sort of impact it has on an application. Reflection allows querying information out of an assembly dynamically and setting and retrieving values from properties/fields as well as dynamically invoking methods at runtime providing a sort of ‘Evaluate’ functionality assuming you have a reference to an object you want to call.
This process is slow compared to direct access of a property, field or method, but it’s hardly a show stopper if used sparingly. You can also bet that the .Net Framework and especially ASP.Net use Reflection internally a fair amount to provide dynamic execution of code and controls, so making one or two calls to Reflection are hardly going to impact performance.
I ran a few very simple tests just to verify that I'M not completely off my rocker here, and sure enough adding a couple of reflection calls to even an empty ASPX page resulted in nearly identical performance results in ACT. The general variance of ACT in short tests actually had the reflection test ahead in 1 of the tests - all the others were also very close with close 250 requests a second against the sample page. In short for a typical ASP.Net page call the overhead was minmal.
Next I ran a couple of simple timing tests in a WinForms app:
//#define CallMethod
//#define GetField
#define SetField
…
protected string Output = "";
…
private void btnStraight_Click(object sender, System.EventArgs e)
{
this.Output = DateTime.Now.ToString();
DateTime Start = DateTime.Now;
for (int x = 0; x < 100000; x++)
{
#if GetField
// *** Get Property Test - note we have to set the value here or else the
// *** compiler will optimize the assignment
this.Output = DateTime.Now.ToString();
string Value = this.Output;
#endif
#if SetField
// *** Set Property Test
this.Output = DateTime.Now.ToString();
#endif
#if CallMethod
this.Output = this.ReturnDate();
#endif
}
DateTime Stop = DateTime.Now;
this.lblResult.Text = ((TimeSpan) Stop.Subtract(Start)).Ticks.ToString("N") + "Ticks.";
}
private void btnReflection_Click(object sender, System.EventArgs e)
{
this.Output = DateTime.Now.ToString();
DateTime Start = DateTime.Now;
for (int x = 0; x < 100000; x++)
{
#if GetField
this.Output = DateTime.Now.ToString();
string Value = (string) this.GetType().GetField( "Output",BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this); //,BindingFlags.Instance | BindingFlags.NonPublic,null,null);
#endif
#if SetField
// *** Set Property Test
this.GetType().GetField( "Output",BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this,DateTime.Now.ToString()); //,BindingFlags.Instance | BindingFlags.NonPublic,null,null);
#endif
#if CallMethod
string value = (string) this.GetType().GetMethod("ReturnDate",BindingFlags.NonPublic | BindingFlags.Instance).Invoke(this,null);
#endif
}
DateTime Stop = DateTime.Now;
this.lblResult2.Text = ((TimeSpan) Stop.Subtract(Start)).Ticks.ToString("N") + "Ticks.";
}
protected string ReturnDate()
{
return DateTime.Now.ToString();
}
The results here were not surprising: Reflection was roughly 2.5-3.0 times slower than direct assignment and retrieval of the property value. Method Invokation was 3.5 to 4 times slower than direct calling of a method.
But keep in mind that this loop ran 100,000 iterations and the entire test ran in under 900 ms without and under 2.5 to a little over 3 seconds with Reflection. The individual call times of these reflected type methods are minmal in the context of a typical application. Slower yes for sure - but having an impact on a typical application? Not likely...
To test this in a real world environment I checked out an ASP.Net page that uses custom databinding that I have implemented that relies fairly extensively on Reflection to bind (and unbind) data to an underlying datasource. I loaded a Web Form that has 35 databound fields on it. I ran the page with databinding enabled and then turned the databinding on the page off completely. Performance ran about 10 slower than without any databinding whatsoever – around 95 requests per second vs. around 85. I was too lazy to add ASP. Net’s default binding to all of the form’s fields but adding it to a few of them showed that the response time of the non-custom binding started falling off. I suspect if all fields were bound there’d be very little difference between my custom binding and ASP. Net’s default binding mechanism (which behind the scenes probably also uses Reflection to assign the values the DataBinder retrieves).
Reflection often gets a bad rap for being slow. True it's much slower than direct access, but it's important to look at performance in the proper perspective. For many operations Reflection and 'evaluative' access to properties, fields and methods provides flexibility that wouldn't otherwise be there.
In short, it’s a good idea to stay away from Reflection when possible, but don’t be afraid to resort to it when it provides a better or more flexible solution to your problem. The performance hit for anything but tight loop operations is likely to be minimal in the overall scheme of an application or Web Form request.