Подтвердить что ты не робот

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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