反射有多慢 [英] How slow is Reflection

查看:17
本文介绍了反射有多慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近创建了一个接口层来区分 DataAccessProvider 和我们的业务逻辑层.通过这种方法,我们可以随时通过更改 Web/App.Config 中的值来更改我们对 DataAccessProvider 的选择.(如果需要,可以提供更多详细信息).

I recently created an interface layer to distinguish the DataAccessProvider from our Business logic layer. With this approach we can change our choice of DataAccessProvider whenever we want by changing the values in the Web/App.Config. (more details can be given if needed).

无论如何,为了做到这一点,我们使用反射来完成我们可以工作的 DataProvider 类.

Anyway, to do this we use reflection to accomplish our DataProvider class on which we can work.

/// <summary>
/// The constructor will create a new provider with the use of reflection.
/// If the assembly could not be loaded an AssemblyNotFoundException will be thrown.
/// </summary>
public DataAccessProviderFactory()
{
    string providerName = ConfigurationManager.AppSettings["DataProvider"];
    string providerFactoryName = ConfigurationManager.AppSettings["DataProviderFactory"];
    try
    {
        activeProvider = Assembly.Load(providerName);
        activeDataProviderFactory = (IDataProviderFactory)activeProvider.CreateInstance(providerFactoryName);
    }
    catch
    {
        throw new AssemblyNotFoundException();
    }
}

但现在我想知道反射有多慢?

But now I'm wondering how slow reflection is?

推荐答案

在大多数情况下:足够快了.例如,如果您使用它来创建 DAL 包装器对象,与需要连接到网络的时间相比,通过反射创建对象所花费的时间将微不足道.所以优化这将是浪费时间.

In most cases: more than fast enough. For example, if you are using this to create a DAL wrapper object, the time taken to create the object via reflection will be minuscule compared to the time it needs to connect to a network. So optimising this would be a waste of time.

如果你在一个紧凑的循环中使用反射,有一些技巧可以改进它:

If you are using reflection in a tight loop, there are tricks to improve it:

  • 泛型(使用包装器 where T : new()MakeGenericType)
  • Delegate.CreateDelegate(对于类型化委托;不适用于构造函数)
  • Reflection.Emit - 核心
  • Expression(类似于 Delegate.CreateDelegate,但更灵活,适用于构造函数)
  • generics (using a wrapper where T : new() and MakeGenericType)
  • Delegate.CreateDelegate (to a typed delegate; doesn't work for constructors)
  • Reflection.Emit - hardcore
  • Expression (like Delegate.CreateDelegate, but more flexible, and works for constructors)

但就您的目的而言,CreateInstance 完全没问题.坚持这一点,让事情变得简单.

But for your purposes, CreateInstance is perfectly fine. Stick with that, and keep things simple.

虽然关于相对性能的观点仍然存在,而最重要的事情仍然是衡量它",但我应该澄清上面的一些内容.有时...确实很重要.先测量.但是,如果您发现它太慢,您可能需要查看类似FastMember,它在后台安静地执行所有 Reflection.Emit 代码,为您提供一个很好的简单 API;例如:

while the point about relative performance remains, and while the most important thing, "measure it", remains, I should clarify some of the above. Sometimes... it does matter. Measure first. However, if you find it is too slow, you might want to look at something like FastMember, which does all the Reflection.Emit code quietly in the background, to give you a nice easy API; for example:

var accessor = TypeAccessor.Create(type);
List<object> results = new List<object>();
foreach(var row in rows) {
    object obj = accessor.CreateNew();
    foreach(var col in cols) {
        accessor[obj, col.Name] = col.Value;
    }
    results.Add(obj);
}

这很简单,但会非常快.在我提到的关于 DAL 包装器的具体示例中——如果你正在做很多事情,请考虑像 dapper 之类的东西,它再次在后台执行所有 Reflection.Emit 代码,为您提供尽可能最快但易于使用的 API:

which is simple, but will be very fast. In the specific example I mention about a DAL wrapper—if you are doing this lots, consider something like dapper, which again does all the Reflection.Emit code in the background to give you the fastest possible but easy to use API:

int id = 12345;
var orders = connection.Query<Order>(
    "select top 10 * from Orders where CustomerId = @id order by Id desc",
    new { id }).ToList();

这篇关于反射有多慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆