我想测量 .NET 运行时加载各个程序集所需的时间。
首先,我准备了以下控制台应用程序:
public static void Main(string[] args)
{
var timer = Stopwatch.StartNew();
var assembly = Assembly.LoadFrom(@"<path to an assembly>");
timer.Stop();
Console.WriteLine($"Assembly: {assembly.FullName}\nLoad time: {timer.Elapsed.TotalMilliseconds}ms");
}
我注意到第一次运行应用程序进行程序集时测量的时间明显更长。
例如,我第一次尝试加载 HdrHistogram.dll 我得到以下结果:
加载时间:51,8103ms
但是,连续运行的结果要低得多,例如:
加载时间:3,1396ms
当我将请求的程序集更改为任何其他程序集时,我看到相同的模式:第一次运行的值较高,连续运行的值较低。
当我重新启动电脑时,第一次运行时测得的加载时间回到初始值,并且在每次连续运行时再次下降。
重新启动机器实际上是获得原始测量值的唯一方法。我尝试重新编译该应用程序,编译并运行另一个应用程序并重新启动控制台。即使对于不相关的 .NET 应用程序,测量值也始终保持较低水平。
我观察到 Assembly.LoadFrom 和 Assembly.Load 方法以及强命名程序集和常规程序集具有相同的行为。
看起来操作系统内存中存在某种形式的程序集缓存,但我找不到任何相关信息,并且无法找到在后台运行的任何 .NET 相关服务。
我有兴趣测量初始加载时间,所以我的问题是:
请参阅应用程序启动时间。该页面是关于 WPF 和 net48 (看起来像),但也应该适用于其他类型的应用程序和 .NET Core。
了解冷启动和热启动
冷启动发生在您的应用程序在系统重新启动后首次启动时,或者当您启动应用程序后关闭它,然后在很长一段时间后再次启动它时。当应用程序启动时,如果Windows内存管理器的备用列表中不存在所需的页面(代码、静态数据、注册表等),则会发生页面错误。需要磁盘访问才能将页面放入内存。
当主要公共语言运行时 (CLR) 组件的大部分页面已加载到内存中时,就会发生热启动,从而节省昂贵的磁盘访问时间。这就是为什么托管应用程序在第二次运行时启动速度更快。