我在C#中编写一个性能关键型应用程序,核心操作是权重计算。该函数如下所示:
public void ForEachWeight(Action<int, int, float> action)
{
for (int lower = 0; lower < LowerLayerSize; lower++) {
for (int upper = 0; upper < UpperLayerSize; upper++) {
action(lower, upper, Weights[(lower * UpperLayerSize) + upper]);
}
}
}
它在几十个地方被调用,具有各种简单的功能,如:
if (activationMethod == ActivationMethod.Binary) {
ForEachWeight((lower, upper, weight) => upperLayer.Values[upper] += weight;
} else {
ForEachWeight((lower, upper, weight) => upperLayer.Values[upper] += lowerLayer.Values[lower] * weight);
}
所有调用都在同一个类中完成,因此所有变量都可以访问。 C#可以内联这些函数调用吗?我想,例如上面的调用可以内联到这样的内容:
if (activationMethod == ActivationMethod.Binary) {
for (int lower = 0; lower < LowerLayerSize; lower++) {
for (int upper = 0; upper < UpperLayerSize; upper++) {
upperLayer.Values[upper] += weight;
}
}
} else {
for (int lower = 0; lower < LowerLayerSize; lower++) {
for (int upper = 0; upper < UpperLayerSize; upper++) {
upperLayer.Values[upper] += lowerLayer.Values[lower] * weight);
}
}
}
如果它没有意味着数以万计的额外函数调用,我认为这是一个巨大的开销。如果这甚至可以提高10%的速度,那么它是完全值得的。我不能通过手动内联它们来进行比较,因为我必须重写大量代码。
所以我的问题是CAN C#内联这些电话?如果是这样,我怎么能知道他们是否被内联?
答案 0 :(得分:11)
内联发生在JIT编译中,因此您需要在运行时检查代码以观察内联。这可以使用调试器来完成,但请记住,如果CLR检测到存在调试器,则会禁用各种优化,因此您需要在编译方法后附加调试器。
答案 1 :(得分:3)
您可以在此属性中使用MethodImplOptions.AggressiveInlining:http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimplattribute.aspx