Будет ли это эффективным способом уменьшить задержки при холодном запуске в .NET? - PullRequest
12 голосов
/ 04 марта 2011

Следующий код ( Виталия Липчинского ) проходит через все типы в сборке и вызывает метод 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 ]

11 голосов
/ 04 марта 2011

Это не сделает запуск быстрее - в конце концов, он делает работу раньше , чем обычно, а не позже. На самом деле может немного замедлить запуск , так как у вас будет другой поток, выполняющий работу, пока ваше приложение пытается запуститься.

Это означает, что к тому времени, когда поток завершится, вы не должны видеть обычную (крошечную) задержку JIT при первом вызове метода. (Конечно, есть и конструкторы, но вы можете включить их, если хотите.)

Кроме того, это, вероятно, означает, что раньше будет использоваться больше памяти, и может быть частью блокировки, участвующей в JIT, работающем с методами, что означает, что вашему «основному» потоку может понадобиться время от времени ждать.

Лично я бы не использовал это "по-настоящему", если бы у меня не было очень веских доказательств того, что это действительно помогает. Во что бы то ни стало проверьте это и попытайтесь получить такие доказательства. Если вы не возражаете против времени запуска, но вам нужно быстрое время отклика , когда вы действительно начнете работать с приложением, оно может помочь.

0 голосов
/ 04 марта 2011

Как обсуждалось в комментариях, может быть достаточным только для предварительной загрузки сборок:

    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);
    }
...