12

以下代码(由 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();
4

2 回答 2

11

它不会使启动更快 - 毕竟,它比通常更早而不是更晚地工作。实际上可能会稍微减慢启动速度,因为当您的应用程序尝试启动时,您将有另一个线程在工作。

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

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

就个人而言,除非我有一些非常好的证据表明它确实有帮助,否则我不会“真正”使用它。无论如何都要测试它并尝试获得这样的证据。如果您不介意启动时间,但希望在实际使用应用程序时获得快速响应时间,这可能会有所帮助。

于 2011-03-04T07:14:18.933 回答
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);
    }
于 2011-03-04T09:27:25.287 回答