预加载所有组件(JIT)

Woz*_*art 4 c# performance jit assemblies .net-assembly

我们正在第一次加载一些重型UI屏幕.我们的项目分为一个主要的可执行文件和几个DLL文件.DLL文件还可以包含UI屏幕,这些屏幕在第一次加载时很慢.

有没有办法(在代码中)我们可以预加载所有引用的程序集,以避免JIT编译命中?

我知道有一种名为NGen的工具.是否可以在开发环境中运行NGen,以便我们可以立即看到它的影响?但理想情况下,我们希望从代码中预加载引用的程序集.

使用C#.NET 3.5和DevExpress作为UI组件.

wal*_*wal 7

你有没有试过/看看这个

也就是说,对于要预先JIT的每个程序集执行以下操作.

static void PreJIT()
{
    foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
    {
        foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly |
                            BindingFlags.NonPublic |
                            BindingFlags.Public | BindingFlags.Instance |
                            BindingFlags.Static))
        {
            System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Cam*_*ron 7

我个人发现将预抖动放在"程序"中有助于某个应用程序,但这是一个特定于具体情况的问题.

更重要的是,wal的答案中的代码在遇到抽象方法时会崩溃,因此添加了两行代码来跳过抽象方法.

static Program()
{
    foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
    {
        foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly |
                            BindingFlags.NonPublic |
                            BindingFlags.Public | BindingFlags.Instance |
                            BindingFlags.Static))
        {
            if ((method.Attributes & MethodAttributes.Abstract) == MethodAttributes.Abstract|| method.ContainsGenericParameters)
            {
                continue;
            }
            System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);
        }
    }
    Console.WriteLine("jitted!");
}
Run Code Online (Sandbox Code Playgroud)


Bal*_*a R 6

看看NGen吧.另一种选择是使用ILMerge将所有程序集合并为一个程序集.每当我使用ILMerge时,我都会添加一个post build命令,以便它自动发生.另一种选择(未经测试)是,如果你不介意更长的启动时间,你可以在每个程序集的开头手动调用Assembly.Load().

  • 加载程序集不会JIT大多数方法(如果有的话).它将强制磁盘访问时间/程序集加载本身更早发生. (2认同)

Dav*_*ita 1

您只需创建位于外部程序集中的类的实例。只需在有限范围内调用构造函数(我的意思是在函数内声明变量。它不应该是全局 var,因为它会延迟 GC 来处置该实例)。这将加载程序集、编译它并缓存它。您甚至可以在后台线程中执行此操作,以便主线程保持响应能力。