是确定性不可行的动作,以及由JIT内联的Func?

时间:2014-12-24 13:32:01

标签: c# optimization inline compiler-optimization jit

标题要求一切。我们在今天的代码中广泛使用动作,带动作的表达式和回调。

JIT可以通过内联来优化这些调用吗?考虑到回调模式,这将是一个巨大的性能提升,在一种形式或另一种形式今天使用荒谬的数量。

JIT无法优化可能永远不会改变的操作。例如,我没有看到为什么动作或功能被标记为" readonly"属性不应该被优化。

例如:

readonly Action a;
readonly Action a1;
readonly Action a2;

a = () => {};
a1 = () => { a() };
a2 = () => { a1() };

IS a2曾经优化过吗?我不明白为什么它不应该成为原因。

2 个答案:

答案 0 :(得分:2)

否,代理人因同样的原因why virtual members cannot be无法进行优化。

  
      
  • 虚拟呼叫:我们不跨越虚拟呼叫。不这样做的原因是我们不知道呼叫的最终目标。我们   可能在这里做得更好(例如,如果99%的电话结束   在同一个目标中,您可以生成执行检查的代码   如果,虚拟调用将要执行的对象的方法表   这不是99%的情况,你打电话,否则你只是执行   内联代码),但不像J语言,大多数调用   我们支持的主要语言不是虚拟的,所以我们不会被迫   如此积极地优化这种情况。
  •   

代理可以在运行时指向任何内容,因此内联并不那么容易。我知道你来自readonly的地方,请记住,readonly不是灵丹妙药。不要忘记反射比readonly更强大,你可以用反射覆盖只读字段。如果方法是内联的,它将执行除委托所指向的其他内容。

因此,显然JIT不会内联您的委托电话。

更新:我发现了一篇有关此主题的有趣文章。 Can a Delegate Invocation be Inlined?

答案 1 :(得分:1)

非优化本身与以下事实有关:它不是一个重要的函数本身,而是它们执行的代码。您为操作分配了const引用,但不保证它们执行的代码不可变和/或能够生成常量行为。如果你不能保证或预测某种不变的行为,内联通常不是一个好主意,因为你可以有不可预测的执行流程,因此行为,这不是.net framework所针对的行为。

在你的具体例子中,我们有简单的,"虚拟"函数,可能会产生一些内联,但这看起来像非常特殊的情况,并且不太可能在某人的代码中发生,所以在.net framework中引入优化将带来微不足道的好处对于每个人,因此,我猜,在CLR中没有实现。

编辑

正如@Sriram Sakthivel所指出的那样:.net runtime中存在反射,因此可能和函数的不可预测的运行时更改可能是这里主要的干扰因素之一,以便允许框架确定给定函数是否是内联的良好候选者。

另外,在@Sriram Sakthivel的答案中@hvd评论,注意为什么readonly关键字特别不能保证确定性的不变性。