【问题标题】:What's faster: expression trees or manually emitting IL更快:表达式树或手动发出 IL
【发布时间】:2013-05-13 20:27:45
【问题描述】:

直接创建一个发出 IL 的方法与创建一个表达式树相比有性能差异吗?

【问题讨论】:

  • 既然我确定你已经尝试过了,请分享你的结果。
  • 我们真的很想知道,表达式树的编译方式是否存在一些根本差异。例如,通过反射执行方法与从表达式树或通过动态绑定调用时方法的执行方式存在根本区别。所以我想知道“编译”表达式树产生的结果是否在某种程度上与手动生成的 IL 产生的结果有很大不同。
  • 两种方法都试一下,拿出一个秒表,你很快就会知道哪个更快。只有这样才能知道。
  • 所以听起来实际上,IL 与表达式树之间没有根本区别。我认为可能存在一些潜在的差异,就像您在通过反射调用方法与通过动态绑定调用或其他类似方法时看到的那样。但听起来情况并非如此。

标签: c# reflection expression-trees reflection.emit


【解决方案1】:

优秀而复杂的问题。在最近之前,Expression 根本无法处理所有场景 - 所以在许多情况下,这不是问题。这随着 Expression.Block 等的引入而改变。在大多数“常见”情况下,Expression 的使用可能绰绰有余,但我承认我没有精确的测量值,原因很简单,虽然我做了很多 IL,但我还针对没有像Expression(当然不是Expression.Block)这样的奢侈品的低级框架。我也倾向于使用复杂的“装饰器”方法,这些方法可以很好地在 IL 中堆叠体操,但不一定要放入 Expression(实际上,如果你的 IL 足够非典型,以至于反射器等人与之斗争,那么它也可能不会映射干净利落的表达 - 我的 IL 往往很粗糙)。

对不起,我不能给你更多的数字数据——关键点:

  • 如果您有较低级别的框架要求,则问题没有实际意义
  • 否则,您必须配置文件

【讨论】:

    【解决方案2】:

    最终,表达式树的 API 实际上只是一个比 reelection.emit 更熟悉的 API,因此它们实际上是等效的,尽管我相信在表达式树中你不能做很多事情,你可以通过直接反射.emit .

    Reflection.Emit 总体上是最快的,但与 for 循环通常比 foreach 更快的方式相同。在许多情况下,您可以使用反射编写比使用表达式 api 执行得更快的代码,但在大多数情况下它们应该是等效的。

    现在,表达式 API 确实有助于成为一种更好的做事方式,原因有几个。

    1. 它的组合方式比使用直接反射.emit 更简单。您可以使用表达式树并重新编写它以添加一些逻辑,这比使用直接 IL 更容易
    2. 将来可能会添加一些优化,您可能无法理解使用方向反射.emit 时不会发生这些优化。

    所以最终,我会说这是一次洗涤。如果它真的很关键,并且您非常了解反射.emit,您通常可以在 IL 中采用一些使用表达式 API 无法获得的快捷方式,但除此之外,在一般用法中,它们应该是相当等价的。

    【讨论】:

    • 完美。这是我所追求的核心,谢谢。
    • 没问题,祝您在进入反射.emit 和/或表达式 api 世界的旅程中好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 2018-03-11
    • 2021-12-29
    • 2014-08-19
    相关资源
    最近更新 更多