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 に答える