我可以检查C#编译器内联方法调用吗?

Ben*_*n S 25 c# optimization compilation inline

我正在写一个XNA游戏,我在那里进行逐像素碰撞检查.通过移位int和按位ORing来检查这种情况的循环通常难以阅读和理解.

我想添加私有方法,例如private bool IsTransparent(int pixelColorValue)使循环更具可读性,但我不希望方法调用的开销,因为这是性能敏感的代码.

有没有办法强制编译器内联这个调用,或者我是否只是希望编译器会进行这种优化?

如果没有办法强制执行此操作,是否有办法检查方法是否内联,而不是读取反汇编?如果内联并且没有其他调用者存在,该方法是否会显示在反射中?

编辑:我不能强迫它,所以我可以检测到它吗?

Ale*_*ort 27

不,你不能.更重要的是,决定内联的人不是带有代码并将其转换为IL的VS编译器,而是带有IL并将其转换为机器代码的JIT编译器.这是因为只有JIT编译器对处理器体系结构有足够的了解才能确定将内联方法放在适当位置,因为它是指令流水线和缓存大小之间的权衡.

因此,即使查看.NET Reflector也无济于事.

  • 我没有说反射,而是说反射器,就像Red Gates .NET Reflector中那样。 (2认同)

Ben*_*n S 16

"你可以检查System.Reflection.MethodBase.GetCurrentMethod().Name.如果方法是内联的,它将返回调用者的名字."

- Joel Coehoorn

  • 当然它只能在运行时工作,即内联时. (22认同)
  • 不在代码中调用这个方法会改变实际的IL,理论上如果它应该被内联,理论上会改变JIT编译器的"推理"吗? (11认同)
  • 是.首先,额外的代码可能会超过32字节的内联限制.因此,如果额外的代码表明它确实被内联,你知道它确实如此.但如果它表明它没有内联,你真的不知道它是否会没有额外的代码. (11认同)

Bry*_*end 15

有一种新方法可以鼓励在这里描述的.net 4.5中更具侵略性的内联:http://blogs.microsoft.co.il/blogs/sasha/archive/2012/01/20/aggressive-inlining-in-the -clr-4-5-jit.aspx

基本上它只是一个标志,告诉编译器如果可能的话内联.不幸的是,它在当前版本的XNA(Game Studio 4.0)中不可用,但是当XNA今年赶上VS 2012时应该可用.如果您以某种方式在Mono上运行,它已经可用.

[MethodImpl(MethodImplOptions.AggressiveInlining)] 
public static int LargeMethod(int i, int j)
{ 
    if (i + 14 > j) 
    { 
        return i + j; 
    } 
    else if (j * 12 < i) 
    { 
        return 42 + i - j * 7; 
    } 
    else 
    { 
        return i % 14 - j; 
    } 
}
Run Code Online (Sandbox Code Playgroud)