.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.
Related Link about Simplified Reflection Access
The Voices of Reason
# re: .Net Reflection and Performance
# re: .Net Reflection and Performance
Anywho, here is my somewhat related post where I referenced this as it came in while writing:
http://blogs.xtras.net/mikes/PermaLink,guid,93d29fdd-5eba-4a29-acf3-1d93dd8ac9a4.aspx
# re: .Net Reflection and Performance
# re: .Net Reflection and Performance
# re: .Net Reflection and Performance
Any help will be appreciated.
# re: .Net Reflection and Performance
My web site have more than 4000 users;
I want to use reflection to set properties;
Forgive me for my bad english, for i am a chinese not good at english.
Any help is presure appreciated
# re: .Net Reflection and Performance
But you have to look at it in relative terms. First ASP.NET already does tons of Reflection based code internally. If you use databindinding (or Eval()/Bind()) of any kind all that goes through reflection. Lots of places reflection is used.
Personally I don't think that reflection usage on page level code that is something to worry about much. It's in framework code, where code loops or is frequently called where special attention really needs to be given to Reflection usage.
In the end only code profiling will help you isolate where bottlenecks in your apps are and my guess it won't be on a few cases of Reflection usage.
# re: .Net Reflection and Performance
I notice that your answer was posted at 1:37 am, is it time zone difference or working hard?
best regard.
# re: .Net Reflection and Performance
Your's advice has always been the most important one since my VFP days.
I am wondering about the impact of reflection's slow nature in a specific context - I have a web service which takes on a message (a serialized object), reads it, refer to an xml to find out mapped information and use reflection to load required assembly, create require class's object and execute required method to get the result back which is returned to caller wrapped in a message again.
Now in my scenario there is a possibility that this web service will be dealing with about 10,000 messages at peak time. Having load balancer in place for the server where web service is deployed, would reflection used in this context be a performance bottelneck?
Thanks,
Vikas
# re: .Net Reflection and Performance
Good article. You raise a very valuable point in that absolutism should be doubted and verified. Microsoft does use extensive reflection within the Page processing life cycle. Any databound control uses reflection. A great example is the datagrid. Even more interesting is how Microsoft managed reflection overhead in the DataGrid.
I have personally observed code where developers will implement custom data binding to emit rows from a Dataset or DataReader and in their algorithm will re-reflect the Properties Collection to get to the PropertyDescriptors the Properties. Apparently the errant developers did not realize that the PropertyDescriptors were reusable and that the really expensive reflection lies in the generation of the Properties collection. Making it worse is that version 1.1 of the framework does not cache the PropertyDescriptorsCollection. Microsoft's design of the DataGrid WebControl showed a keen awareness of this and they really optimized the grid to prevent re-reflection by caching their property descriptors and reusing them.
My point is this: not only do people have to be concerned with performance regarding the use of PropertyDescriptors and invocation of Methods via Reflection, they need to be keenly aware of how they are USING reflection.
As developers we frequently talk about code re-use, frameworks, and maintainable code but without Reflection how could you for example write a data binding algorithm to deal with disparate datasources (e.g. DataReader, DataSet, collection of Objects)? Many developers would have Dataset specific code, DataReader specific code and so on. Using reflection coupled with a knowledge of the System.ComponentModel namespace a develoepr could create single, scalable, performant software layer that binds any of the objects that I mentioned). Reflection is powerful and if misused can create performance issues. As you rightly point out; when used properly developers should not have significant impact on their systems performance.
In my opinion Reflection is the gateway to the next "level" in .Net programming.
# re: .Net Reflection and Performance
I'm also wondering should I use a reflaction in my App or not. Browsing the web for the answer wasn't very successful, yet...;)
So, as I assumed and you also pointed out, .NET internally uses reflection as well. But there is a fact, that reflection is slower, which is obviuos, since the code is not compiled, meaning that the function doesn't know what kind of object will it get, for example.
My case, where using reflection would come very handy is this. I'm building a multilayer app and I would like to have a generic DataAccessLayer class, to handle most of object and their communication with DB. The idea is to have a function that handles an update and /or insert events for any kind of object passed to it. It gets a BaseClass object from which all the others are dervied from. Than I would like to use reflection, to get the type of it and get it's properties, methods and parameters. It would save me a bunch of time during development, but I'm concerened about performance. Since this would be a part of framework, it would be implemented largely and in different type of apps (from webpages to bussiness apps, intranets...). I wonder,if this is reasonable,or it is better to code every DB class for itself, just for perfomance sake?
Her is a snippet of my code, where I use reflection. It is called every time I insert or update ANY object:
//generic request for insert / update
public void Change(Basic item)
{
PropertyInfo[] properties = item.GetType().GetProperties();
NeoDatabaseAccess nda = new NeoDatabaseAccess();
SqlCommand cmd = nda.GetCommand("sp" + item.Entity + "_Change");
//get each property in the item
foreach (PropertyInfo property in properties)
{
if (property.Name != "EntityID" && property.Name != "Entity" && property.Name != "Instance")
{
//add each property as a parameter
MethodInfo method = item.GetType().GetMethod("get_" + property.Name);
ParameterInfo[] info = item.GetType().GetMethod("get_" + property.Name).GetParameters();
cmd.Parameters.AddWithValue("@" + property.Name, method.Invoke(item, info));
}
}
cmd.Parameters["@InstanceID"].Direction = ParameterDirection.InputOutput;
item.InstanceID = Convert.ToInt32(cmd.ExecuteScalar());
nda.Dispose();
}
So any poniter, suggestion or opinion would be greatly appreciated!
Thanks in advance, Matic
# re: .Net Reflection and Performance
http://kennethxu.blogspot.com/2009/05/strong-typed-high-performance_15.html
# re: .Net Reflection and Performance
{
Animal Animal1 = objectA as Animal;
}
I guess my question is this: Does 'object is Type' have the same performance hit as 'object.GetType()' ?
# re: .Net Reflection and Performance
# re: .Net Reflection and Performance
# re: .Net Reflection and Performance
StopWatch class is really helpful in performance tests: http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx
# re: .Net Reflection and Performance
Normal test used: 1500ms
NormalPlinq test used: 786ms
Reflect test used: 2923ms
ReflectCache test used: 2576ms
ReflectCachePlinq test used: 1353ms
You can see on a dual-core PC, PLINQ doubles the performance and bring our cached reflection code FASTER than normal call; on the other hand PLINQ double the normal call performance too :)
Any other way to optimize our reflection code?
Any ways to avoid boxing/unboxing if we are dealing with value types?
Console c# source code running on VS2010 RC:
using System; using System.Diagnostics; using System.Reflection; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { private String Output { get; set; } static void Main(string[] args) { var p = new Program(); var stopwatch = new Stopwatch(); stopwatch.Start(); p.TestNormal(stopwatch); stopwatch.Restart(); p.TestNormalPlinq(stopwatch); stopwatch.Restart(); p.TestReflection(stopwatch); stopwatch.Restart(); p.TestReflectionCached(stopwatch); stopwatch.Restart(); p.TestReflectionCachedPlinq(stopwatch); } string ReturnDate() { return DateTime.Now.ToString(); } void TestNormal(Stopwatch stopwatch) { this.Output = DateTime.Now.ToString(); for (int x = 0; x < 200000; x++) { // *** Get Property Test - note we have to set the value here or else the compiler will optimize the assignment this.Output = DateTime.Now.ToString(); var Value = this.Output; // *** Set Property Test this.Output = DateTime.Now.ToString(); this.Output = this.ReturnDate(); } Debug.WriteLine("Normal test used: " + stopwatch.ElapsedMilliseconds + "ms"); } void TestNormalPlinq(Stopwatch stopwatch) { this.Output = DateTime.Now.ToString(); Parallel.For(0, 200000, (i) => { // *** Get Property Test - note we have to set the value here or else the compiler will optimize the assignment this.Output = DateTime.Now.ToString(); var Value = this.Output; // *** Set Property Test this.Output = DateTime.Now.ToString(); this.Output = this.ReturnDate(); }); Debug.WriteLine("NormalPlinq test used: " + stopwatch.ElapsedMilliseconds + "ms"); } void TestReflection(Stopwatch stopwatch) { for (int x = 0; x < 200000; x++) { this.Output = DateTime.Now.ToString(); string Value = (string) this.GetType().GetProperty("Output", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this, null); //,BindingFlags.Instance | BindingFlags.NonPublic,null,null); // *** Set Property Test this.GetType().GetProperty("Output", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, DateTime.Now.ToString(), null); //,BindingFlags.Instance | BindingFlags.NonPublic,null,null); string value = (string) this.GetType().GetMethod("ReturnDate", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(this, null); } Debug.WriteLine("Reflect test used: " + stopwatch.ElapsedMilliseconds + "ms"); } void TestReflectionCached(Stopwatch stopwatch) { var pi = this.GetType().GetProperty("Output", BindingFlags.Instance | BindingFlags.NonPublic); var mi = this.GetType().GetMethod("ReturnDate", BindingFlags.Instance | BindingFlags.NonPublic); Func<string> getter = () => (string) pi.GetValue(this, null); Action<string> setter = (s) => pi.SetValue(this, s, null); Func<string> getMethod = () => (string) mi.Invoke(this, null); for (int x = 0; x < 200000; x++) { this.Output = DateTime.Now.ToString(); string Value = getter(); setter(DateTime.Now.ToString()); string value = getMethod(); } Debug.WriteLine("ReflectCache test used: " + stopwatch.ElapsedMilliseconds + "ms"); } void TestReflectionCachedPlinq(Stopwatch stopwatch) { var pi = this.GetType().GetProperty("Output", BindingFlags.Instance | BindingFlags.NonPublic); var mi = this.GetType().GetMethod("ReturnDate", BindingFlags.Instance | BindingFlags.NonPublic); Func<string> getter = () => (string)pi.GetValue(this, null); Action<string> setter = (s) => pi.SetValue(this, s, null); Func<string> getMethod = () => (string)mi.Invoke(this, null); Parallel.For(0, 200000, (i) => { this.Output = DateTime.Now.ToString(); string Value = getter(); setter(DateTime.Now.ToString()); string value = getMethod(); }); Debug.WriteLine("ReflectCachePlinq test used: " + stopwatch.ElapsedMilliseconds + "ms"); } } }
# re: .Net Reflection and Performance
Yes, bind your method to delegate and cache the delegate. You get nearly normal performance. For field access, you'll need dynamic method. See link below for detail:
http://kennethxu.blogspot.com/2009/05/strong-typed-high-performance_15.html
# re: .Net Reflection and Performance
Use them if there is no better alternative.