c# 中的内联辅助方法
Inline helper methods in c#
从 this answer 我了解到可以强烈建议在 C# 中进行内联,如下所示:
using System.Runtime.CompilerServices;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
bool MyCondition() { return someObject != null && someObject.Count > 2; }
在当前的项目中,我们使用由 Appccelerate StateMachine 框架定义的状态机,这导致序列如下(在我们的项目中更长):
fsm.In(States.A)
.On(Events.B)
.If(arguments => false).Goto(States.B1)
.If(() => someVariable && somethingElse == false).Goto(States.B3);
.If(MyCondition).Goto(States.B2)
为了简化这些结构,我想将 lambda 表达式(或 Action 委托)分成辅助方法(即最后一条语句)。这样做的原因是,使用适当的方法名称可以提高代码的可读性,其次,当自动生成文档时,它将使用方法名称而不是非直观的 [anonymous]
文本。
然而,问题是使用 AggressiveInlining
是否有任何意义,或者涉及最多 4 个变量和简单比较运算符的简单 lambda 表达式是否会被 JIT/compiler 自动内联?
我的直觉是内联这些方法,因为我相信状态机的不同部分会得到很多点击,因此减少方法调用将是一个好处。但是话又说回来 JIT/compiler 自动执行此操作有多聪明?
问题是您对 c# 中的 lambda 的理解不正确。当编译器将 c# 翻译成 MSIL 时,lambdas 变成 classes,所以你没有什么可以内联的。你可以看看很棒的Marc Gravell post on SO。因此,无论您是否在外部 class 中定义 lambda,您都需要从堆中获取一个对象(我简化了编译后的代码行为)。因此,正如我认为的那样,您的应用程序的性能不会有任何差异。
另请记住,状态机将委托保留在其内部数据结构中。守卫动作不能在那里内联。
唯一可能的是内联辅助方法调用的方法。
从 this answer 我了解到可以强烈建议在 C# 中进行内联,如下所示:
using System.Runtime.CompilerServices;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
bool MyCondition() { return someObject != null && someObject.Count > 2; }
在当前的项目中,我们使用由 Appccelerate StateMachine 框架定义的状态机,这导致序列如下(在我们的项目中更长):
fsm.In(States.A)
.On(Events.B)
.If(arguments => false).Goto(States.B1)
.If(() => someVariable && somethingElse == false).Goto(States.B3);
.If(MyCondition).Goto(States.B2)
为了简化这些结构,我想将 lambda 表达式(或 Action 委托)分成辅助方法(即最后一条语句)。这样做的原因是,使用适当的方法名称可以提高代码的可读性,其次,当自动生成文档时,它将使用方法名称而不是非直观的 [anonymous]
文本。
然而,问题是使用 AggressiveInlining
是否有任何意义,或者涉及最多 4 个变量和简单比较运算符的简单 lambda 表达式是否会被 JIT/compiler 自动内联?
我的直觉是内联这些方法,因为我相信状态机的不同部分会得到很多点击,因此减少方法调用将是一个好处。但是话又说回来 JIT/compiler 自动执行此操作有多聪明?
问题是您对 c# 中的 lambda 的理解不正确。当编译器将 c# 翻译成 MSIL 时,lambdas 变成 classes,所以你没有什么可以内联的。你可以看看很棒的Marc Gravell post on SO。因此,无论您是否在外部 class 中定义 lambda,您都需要从堆中获取一个对象(我简化了编译后的代码行为)。因此,正如我认为的那样,您的应用程序的性能不会有任何差异。
另请记住,状态机将委托保留在其内部数据结构中。守卫动作不能在那里内联。
唯一可能的是内联辅助方法调用的方法。