【问题标题】:What Performs Worse: Reflection or Boxing?什么表现更差:反射还是拳击?
【发布时间】:2010-02-12 22:03:32
【问题描述】:

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

这引发了一个关于值类型的有趣问题。哪个性能最好:

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

b) 选择老式的参数 Object[] 并在拳击上大放异彩?

【问题讨论】:

  • 为什么这个“学习练习”不涉及分析各种设置以找到最佳解决方案? ;-) 不过,我仍然会给 +1。
  • c) 使用带有泛型参数的重载?
  • 不太可能,Expression.Call 采用 MethodInfo,因此您必须预先选择具有正确类型的正确方法。
  • 哪个较慢无关紧要。相关的问题是它们中的任何一个对于您的应用程序是否足够快?如果事实证明对于您的应用程序来说两者都不够快,那么知道哪个更慢也无济于事。如果事实证明两者都足够快,那么知道哪个更慢在很大程度上是无关紧要的。
  • @Eric Lippert 感谢您的评论,我认为我的标题太消极了,我更感兴趣的是扩展我对反射 v 拳击的性能影响的理解,以帮助我更好地理解 CLR 和 C#。

标签: c# .net performance reflection boxing


【解决方案1】:

IME,装箱时间与反射相比算不了什么。

【讨论】:

    【解决方案2】:

    我猜反射会慢很多,可能是数量级。

    不过,这很容易做替补,试一试并发布你的结果 :)

    【讨论】:

      【解决方案3】:

      在这种情况下,装箱将比反射快几个数量级。

      当然,你总是可以缓存反射结果。

      【讨论】:

        【解决方案4】:

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

        正如其他人所说,反射在这里是较慢的(除非你不缓存)。拳击受青睐的另一件事是在处理反射时,您很可能还是在拳击。反射 API 总是处理object,所以如果你要取回一些实例值,你必须拆箱。同样,calling GetType on a value type instance first boxes it to object 如果您没有类型参数,但只有实例,您可能必须这样做。

        但更好的选择是依赖泛型。一些不错的图案详解here.

        【讨论】:

          【解决方案5】:

          如果必须处理一百万个项目,装箱每个项目的效率将低于不装箱处理它们,但会比使用反射处理每个项目的类型快得多。

          另一方面,在许多情况下,通过在类型 T 上使用一次反射来构造一个可以处理 @987654323 类型的对象,可以处理一百万个通用类型 T 的项目@ 没有装箱,然后在程序的生命周期内缓存该结果。这就是EqualityComparer<T>.Default 之类的工作方式。这种方法很容易比对每个项目进行装箱快一个数量级以上。

          【讨论】:

          • 请记住,您仍然需要访问反射缓存,很可能是通过字典。如果一个小拳击仍然比那些查找更快,我不会感到惊讶 - 特别是如果涉及字符串键(可能是也可能不是这种情况)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-14
          • 2014-06-19
          • 2010-09-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多