更糟糕的是:反思还是拳击?

时间:2010-02-12 22:03:33

标签: c# .net performance reflection boxing

我正在创建自己的DI框架,创建委托工厂作为学习练习。我构建类型委托的方法是使用表达式来创建一个函数,该函数通过引用我的容器和任何构造函数参数来调用静态方法。

这引发了一个关于价值类型的有趣问题。哪个是最高效的:

a)使用反射选择具有正确参数数量的静态通用方法,然后使用MakeGenericMethod删除泛型

b)去旧时尚参数对象[]并参加拳击比赛?

5 个答案:

答案 0 :(得分:16)

IME,拳击时间与反射无关。

答案 1 :(得分:3)

我猜测反射会慢得多,可能是数量级的。

虽然很容易进行替补,但要试一试并发布结果:)

答案 2 :(得分:3)

在这种情况下,拳击比反射快几个数量级。

当然,您可以随时缓存反射结果。

答案 3 :(得分:2)

一般来说,我会说即使拳击速度较慢(在某种程度上不明显),它也是正确的方法。反射是一种促进某种元编程的工具 - 当你必须对代码本身做一些工作,而不是为了促进你的应用程序业务逻辑,因此你不应该没有充分的理由使用它。程序员应首先从物理域思考。也就是说,在你的情况下它可能并不重要,因为你已经采用元方式我认为。使用object仍然可以在一定程度上为您提供编译时安全性以及更好的维护

正如其他人所说,反射在这里比较慢(除非你不缓存)。对拳击有利的另一件事是你最有可能在处理反射时无论如何拳击。反射API始终处理object,因此如果要获取某些实例值,则必须取消装箱。类似地,如果你没有type参数,那么你可能需要calling GetType on a value type instance first boxes it to object,但只有实例。

但更好的选择是依靠仿制药。一些不错的模式详细here.

答案 4 :(得分:1)

如果必须处理一百万个项目,装箱每个项目的效率将低于没有装箱处理它们的效率,但是比使用Reflection处理每个项目的类型要快得多。

另一方面,在许多场景中,可以通过在类型T上使用Reflection一次来处理一些泛型类型T的一百万个项目来构造一个可以处理某些东西的对象类型T没有装箱,然后缓存程序生命周期的结果。这就是EqualityComparer<T>.Default之类的事情。这样的方法很容易比装箱每件物品快一个数量级。

相关问题