这是否是改善.NET冷启动延迟的有效方法?

时间:2011-03-04 07:05:31

标签: c# cold-start

以下代码(by Vitaliy Liptchinsky)遍历程序集中的所有类型,并在所有方法上调用PrepareMethod。这会改善冷启动延迟吗?

    Thread jitter = new Thread(() =>
    {
      foreach (var type in Assembly.Load("MyHavyAssembly, Version=1.8.2008.8," + 
               " Culture=neutral, PublicKeyToken=8744b20f8da049e3").GetTypes())
      {
        foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly | 
                            BindingFlags.NonPublic | 
                            BindingFlags.Public | BindingFlags.Instance | 
                            BindingFlags.Static))
        {
            if (method.IsAbstract || method.ContainsGenericParameters)
                    continue;
            System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);
        }
      }
    });
    jitter.Priority = ThreadPriority.Lowest;
    jitter.Start();

2 个答案:

答案 0 :(得分:11)

它不会让启动更快 - 毕竟,它正在之前工作,而不是通常而不是以后。实际上可能会放慢启动,因为当你的应用程序尝试启动时,你会有另一个线程在工作。

这意味着在线程完成时,您第一次调用方法时不应该看到正常(微小)JIT延迟。 (当然也有构造函数,但如果需要,可以包含它们。)

此外,它可能意味着更早的内存将被使用,并且可能是JIT处理方法所涉及的一些锁定,这意味着您的“主”线程可能需要偶尔等待。

我个人不会“真实地”使用它,除非我有一些非常好的证据表明它实际上有所帮助。通过各种方式测试它并试图获得这样的证据。如果你不介意启动时间,但是当你真正使用应用程序时想要一个快速的响应时间,可以帮助。

答案 1 :(得分:0)

正如评论中所讨论的那样,可能足以预加载程序集:

    static void PreloadAssemblies()
    {
        int count = -1;
        Debug.WriteLine("Loading assemblies...");
        List<string> done = new List<string>(); // important...
        Queue<AssemblyName> queue = new Queue<AssemblyName>();
        queue.Enqueue(Assembly.GetEntryAssembly().GetName());
        while (queue.Count > 0)
        {
            AssemblyName an = queue.Dequeue();
            if (done.Contains(an.FullName)) continue;
            done.Add(an.FullName);
            try
            {
                Assembly loaded = Assembly.Load(an);
                count++;
                foreach (AssemblyName next in loaded.GetReferencedAssemblies())
                {
                    queue.Enqueue(next);
                }
            }
            catch { } // not a problem
        }
        Debug.WriteLine("Assemblies loaded: " + count);
    }