【问题标题】:Can I have a concise code snippet that would incur JIT inlining please?请问我可以有一个简洁的代码片段会导致 JIT 内联吗?
【发布时间】:2012-10-02 08:26:50
【问题描述】:

我正在尝试生成一些会导致 JIT 内联的“Hello World”大小的 C# 代码 sn-p。到目前为止,我有这个:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine( GetAssembly().FullName );
        Console.ReadLine();
    }

    static Assembly GetAssembly()
    {
        return System.Reflection.Assembly.GetCallingAssembly();
    }
}

我从 Visual Studio 编译为“Release”-“Any CPU”和“Run without debugging”。它清楚地显示了我的示例程序程序集的名称GetAssembly() 没有内联到Main(),否则它将显示mscorlib 程序集名称。

如何编写一些会导致 JIT 内联的 C# 代码 sn-p?

【问题讨论】:

  • 我认为内联会改变程序的可观察行为,我想你一定会失望 :)
  • @jalf:即使使用反射?
  • @jalf:这不太正确。例如,堆栈跟踪确实受到内联的影响。
  • @DanielHilgarth:堆栈跟踪不算作“可观察行为”:)

标签: c# .net jit inlining


【解决方案1】:

当然,这是一个例子:

using System;

class Test
{
    static void Main()
    {
        CallThrow();
    }

    static void CallThrow()
    {
        Throw();
    }

    static void Throw()
    {
        // Add a condition to try to disuade the JIT
        // compiler from inlining *this* method. Could
        // do this with attributes...
        if (DateTime.Today.Year > 1000)
        {
            throw new Exception();
        }
    }
}

以类似发布的模式编译:

csc /o+ /debug- Test.cs

运行:

c:\Users\Jon\Test>test

Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
   at Test.Throw()
   at Test.Main()

注意堆栈跟踪 - 看起来 Throw 似乎是由 Main 直接调用的,因为 CallThrow 的代码是内联的。

【讨论】:

    【解决方案2】:

    您对内联的理解似乎不正确:如果 GetAssembly 被内联,它仍然会显示您的程序名称。

    内联意味着:“在函数调用的地方使用函数体”。内联GetAssembly 将导致代码与此等效:

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(System.Reflection.Assembly.GetCallingAssembly()
                                                        .FullName);
            Console.ReadLine();
        }
    }
    

    【讨论】:

    • 我认为他的观点是GetAssembly 会被Main 调用,但Main 会被mscorlib 中的某些东西调用。
    • @Rawling:这不是他在问题中所说的:“显然GetAssembly() 没有内联到Main()
    • System.Reflection.Assembly.GetCallingAssembly() 如果直接在 main 中调用会返回不同的结果,就像在 main 调用的函数中调用时一样。您的代码产生的结果与原始代码不同。因此,如果发生内联将他的代码转换为您的代码,输出不同。
    • @Rawling:这不正确。你可以自己测试一下。
    • 如果我将您的代码和问题代码结合起来 - 例如一个WriteLineSystem.Reflection.Assembly.GetCallingAssembly(),一个与GetAssembly() - 我得到两个不同的输出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多