Would this be an effective way to improve cold-start delays in .NET?
The following code (by Vitaliy Liptchinsky) goes through all types in an assembly and calls PrepareMethod on all methods. Would this improve cold-start delays?
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开发者_如何学Python (method.IsAbstract || method.ContainsGenericParameters)
continue;
System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);
}
}
});
jitter.Priority = ThreadPriority.Lowest;
jitter.Start();
It won't make startup any faster - after all, it's doing work earlier than it normally would rather than later. In fact could will slow down startup slightly, as you'll have another thread doing work while your app is trying to start.
It means that by the time that thread has finished, you shouldn't see the normal (tiny) JIT delay when you call a method for the first time. (Of course there are also constructors, but you could include them if you want.)
Additionally it probably means more memory will be used earlier, and there may be some locking involved in the JIT working on methods which means your "main" thread may need to wait occasionally.
Personally I wouldn't use it "for real" unless I had some very good evidence to suggest it's actually helping. By all means test it and try to get such evidence. If you don't mind startup time, but you want a swift response time when you come to actually work with the application, it may help.
As discussed in comments, it might be sufficient just to preload the assemblies:
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);
}
精彩评论