簡體   English   中英

執行前預編譯C#方法

[英]Precompile C# method before executing

我像這樣測量代碼速度:

var sw = new Stopwatch();
sw.Start();
DoSomething();
sw.Stop();
AddLog("Method speed is (ms): "+sw.ElapsedMilliseconds);

但是DoSomething()的第一次調用很慢,因為代碼正在編譯。 解決方法是測量第二次調用的速度,如下所示:

var sw = new Stopwatch();
DoSomething();
sw.Start();
DoSomething();
sw.Stop();
AddLog("Method speed is (ms): "+sw.ElapsedMilliseconds);

是否可以在沒有第一次調用的情況下預編譯DoSomethig()?

文檔沒有明確說明的話,但根據文章(等等),你可以使用RuntimeHelpers.PrepareMethod預編譯的方法。

要詳細說明我的評論(上述),這里是一個代碼示例:

static void WarmUp()
{
    var handle = typeof (Program).GetMethod("DoSomething").MethodHandle;
    RuntimeHelpers.PrepareMethod(handle);
}

更新

這是一個更通用的(雖然有點脆弱)解決方案,它也會考慮實例成員:

public static class MethodWarmerUper
{
    public static void WarmUp(string methodName)
    {
        var handle = FindMethodWithName(methodName).MethodHandle;
        RuntimeHelpers.PrepareMethod(handle);
    }

    private static MethodInfo FindMethodWithName(string methodName)
    {
        return 
            Assembly.GetExecutingAssembly()
                    .GetTypes()
                    .SelectMany(type => type.GetMethods(MethodBindingFlags))
                    .FirstOrDefault(method => method.Name == methodName);
    }

    private const BindingFlags MethodBindingFlags =
        BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic |
        BindingFlags.Instance | BindingFlags.Static;
}

您看到這種時間差異的原因是因為運行時正在編譯第一次調用之前執行的方法,而當它即將被第二次調用時,運行該方法所需的所有內容都已編譯完畢。 您可以使用ngen.exe執行此任務。 它在執行之前將il編譯為本機exe,並將減少啟動時間。

對於您的特定場景,我相信ngen.exe是適合該作業的工具,因為它可以作為post build事件觸發,以提前編譯您的程序集並在您需要時做好准備。 如果你使用PrepareMethod,那么當你運行測試時,你仍然會延遲JITing方法,而不是在實際調用它們時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM