.Net Reflection and Performance

本文探讨了ASP.Net中反射对应用程序性能的影响。有人担心反射会严重影响性能,但实际上少量使用反射对性能影响不大。通过简单测试发现,反射虽比直接访问慢,但在典型应用中单次调用开销极小,在实际环境中影响也有限,应合理使用反射。

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.

<?xml:namespace prefix = o />

 

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.

转载于:https://www.cnblogs.com/lovewindy/archive/2005/02/19/105942.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值