C# 如何内联我的内部函数?
TL;DR:我是否可以创建一个算法,该算法可以在内部循环中使用不同的功能,并且仍然可以内联“功能”,而无需使用复制/粘贴或if/else语句 我试图创建一个基本上如下所示的算法:C# 如何内联我的内部函数?,c#,inline,C#,Inline,TL;DR:我是否可以创建一个算法,该算法可以在内部循环中使用不同的功能,并且仍然可以内联“功能”,而无需使用复制/粘贴或if/else语句 我试图创建一个基本上如下所示的算法: for(var i=0; i<big; i++) { for(var j=0; j<big2; j++) { // ... processing var x = SomeFunc(a, b, c); // ... more processing } } 但是函数调用似
for(var i=0; i<big; i++) {
for(var j=0; j<big2; j++) {
// ... processing
var x = SomeFunc(a, b, c);
// ... more processing
}
}
但是函数调用似乎不是内联的,因为上面的func
是通过接口而不是通过密封类调用的
我还尝试了显而易见的方法:
abstract class MyAlgo {
protected abstract int SomeFunc(int a, int b, int c);
public void Run() {
// as RunMyGenericAlgo above
}
}
sealed class MyAlgoSomeFunc1 : MyAlgo {
protected override int SomeFunc(int a, int b, int c) {...}
}
而且它也没有内联
但是,该程序将根据需要进行内联(并且运行速度大约快50%):
EDIT:为了澄清,我还使用了带有aggressiveinline
的MethodImpl
属性进行了调查,但似乎没有任何帮助
我在C#中尝试的是可能的吗?或者我必须为我的内部函数的每个实现复制/粘贴我的算法吗?要允许方法内联,实现必须是常量(例如,不依赖于变量)。因此,根据定义,任何形式的虚拟/抽象/接口/委托调用都是无法内联的调用。 因此,唯一的方法是使用非虚拟方法调用,或者只是将代码粘贴到其中 这条规则有一些例外。例如,JVM设计人员遇到的问题是,默认情况下,所有Java方法都是虚拟的,它们具有虚拟调用内联。这将执行以下操作:
//calling obj.MyVirtCall();
if (obj.Type == MyCommonType) {
//inlined code for MyCommonType.MyVirtCall();
} else {
obj.MyVirtCall();
}
编辑:
在您的算法示例中,您可以为
Run
的每个重写生成C代码,不需要重复代码,但这可能会使维护稍微复杂一些,还必须维护T4模板而不仅仅是C代码。您给出的代码的可能重复甚至无效,asSomeFunc1.SomeFunc
需要是公共的(或显式实现接口)。不过我建议你使用代理。不,这并不意味着算法会多次抖动。。。如果SomeFunc1
是一个结构,就可以了。)你有没有任何迹象表明内联在这种情况下真的很重要?@dav_我不认为这个问题是重复的,因为它通常涉及内联(并且似乎把内联与lambdas混淆)。@jonsket是的,我已经做了测量。内联(复制+粘贴代码并仅使用非虚拟代码)可节省约50%的挂钟时间。对于伪代码很抱歉,我试图保留它只是作为一个说明。当然,我的测试程序是有效的,但它太长了,无法发布。@Krumelur-I认为“50%的挂钟时间”太离谱了。差别应该很小。实际上,.NET也会这样做。就像在Java中一样,它只有在其中一个实现明显占主导地位时才真正起作用(我认为这个数字大约是对特定方法的500:1调用与虚拟方法的调用之比)。
class MyAlgo {
int SomeFunc(int a, int b, int c) {...}
public void Run() {
// as above
}
}
//calling obj.MyVirtCall();
if (obj.Type == MyCommonType) {
//inlined code for MyCommonType.MyVirtCall();
} else {
obj.MyVirtCall();
}