提问人:amymor 提问时间:10/29/2023 最后编辑:amymor 更新时间:10/30/2023 访问量:144
为什么 .NET 应用程序至少有一秒的启动延迟?[关闭]
Why do .NET applications have at least a one-second startup delay? [closed]
问:
我一直在寻找一种具有以下参数的语言:
简单易读的语法。
能够轻松创建 Windows 用户界面。
对 Windows 应用程序的本机支持。
卓越的性能和快速的启动时间。
可移植性,无需像 10-20 GB Visual Studio IDE 那样进行大量安装。
它应该已经被广泛使用并拥有一个庞大的社区。
我发现 VB6 满足了我的需求,但不幸的是,它不再受支持。因此,我尝试了 VB .NET。我发现转换非常容易,与 C#/C++ 相比,VB 代码更具可读性和简洁性。正如我所提到的,我不想安装任何东西,所以我没有尝试 .NET 6 和 7。我的目标是尽可能多地使用内置工具或便携式工具。但是,.NET Framework 的问题在于,无论代码的权重或使用的语言(VB 或 C#)如何,启动时间始终保持在 1-2 秒之间。相比之下,VB6 应用程序会立即启动。下面是用 VB .NET 编写的示例:vbc.exe
Imports System.Windows.Forms
Imports System.Drawing
Public Class Form1
Inherits Form
Private WithEvents button As New Button()
Private WithEvents textBox As New TextBox()
Public Sub New()
button.Text = "Browse"
button.Location = New Point(10, 10)
Me.Controls.Add(button)
textBox.Location = New Point(10, 40)
Me.Controls.Add(textBox)
End Sub
End Class
Module Module1
Sub Main()
Application.Run(New Form1)
End Sub
End Module
我做了什么:
1.
CD C:\Windows\Microsoft.NET\Framework64\v4.0.30319
NGEN update
我尝试了(和)编译器的各种选项,例如和。
vbc.exe
csc.exe
/optimize[+|-]
/platform
不同版本的 .NET Framework(32 位和 64 位),包括版本 2、3.5 和 4.x.x。
使用以下命令编译我的应用程序:
msbuild.exe
msbuild /property:Configuration=Release;UseDotNetNativeToolchain=true MyFile.vbproj
,
以下是 MyFile.vbproj 的内容:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Sdk="Microsoft.NET.Sdk" >
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<ItemGroup>
<Compile Include="DiCalc.vb" />
</ItemGroup>
<Target Name="Build">
<Vbc Sources="@(Compile)" OutputAssembly="DiCalc.exe" TargetType="WinExe"/>
</Target>
</Project>
提前致谢。
更新1:
- 我的系统上没有安装任何防病毒软件。SmartScreen 筛选器和 Windows Defender 当前均处于禁用状态。
- 我不使用任何共享网络文件夹。实际上,我在 M.2 NVMe SSD 上对其进行了测试。
更新2:以下是更详细的测试:
测试.VB
Imports System.Windows.Forms
Imports System.Drawing
Public Class Form1
Inherits Form
Private button As New Button()
Public Sub New()
Me.BackColor = Color.FromArgb(14, 14, 14)
Me.ForeColor = Color.FromArgb(240, 240, 240)
button.Text = "Browse"
button.Location = New Point(10, 10)
button.BackColor = Color.FromArgb(14, 14, 14)
button.ForeColor = Color.FromArgb(240, 240, 240)
Me.Controls.Add(button)
End Sub
End Class
Module Module1
Sub Main()
Application.Run(New Form1)
End Sub
End Module
编译命令:
64 倍
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\vbc.exe /t:winexe /platform:x64 /out:VB.NET-x64.exe test.vb
x86的
C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe /t:winexe /platform:x86 /out:VB.NET-x86.exe test.vb
平均延迟:
VB.NET-x64.exe => ~320 ms
VB.NET-x86.exe => ~650 ms
VB6-x86.exe => ~80 ms
因此,VB6 的启动时间比 VB.NET 快 4 到 8 倍。
注意:要查看实际延迟,请确保禁用动画,并通过文件夹选项a启用资源管理器中的单击。
更新 3:我下载了 .NET 8 SDK zip 存档来测试它并确定提前 (AOT) 编译是否会缩短启动时间,类似于 VB6。以下是 .vbproj 文件的内容:
<Project Sdk="Microsoft.NET.Sdk" >
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<PublishAot>true</PublishAot>
<StripSymbols>true</StripSymbols>
<PublishTrimmed>false</PublishTrimmed>
<SelfContained>true</SelfContained>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Windows.Forms" />
</ItemGroup>
</Project>
编译命令:
dotnet.exe build /p:Configuration=Release /p:UseNativeAOT=true
结果是一个大小约为 150MB 的应用程序,但延迟与以前相同。
答:
首先,我的 vb.net 应用程序都没有在启动时出现这样的延迟。
如果创建 vb.net Windows .net Framework 窗体应用程序,则启动时间不会显示延迟,甚至没有可察觉的启动延迟。
所以,让我们做一个hello world:
File->new 项目。
这个:
因此,让我们构建该类 hello world 示例。
我们在窗体上拖动一个按钮,从而编写以下代码:
然后 f5 运行..
(实际上,我们使用鼠标并点击开始按钮)。
当然,我们从Visual Studio运行它,但是让我们右键单击项目,选择“在浏览中打开文件夹”,然后从Windows资源管理器运行.exe文件(而不是从Visual Studio运行/启动)。因此,让我们从 Windows 资源管理器(甚至命令提示符)启动 .exe 文件。
所以,我们现在有了这个文件夹,当我单击 .exe 文件时,我没有看到 2 秒的等待,我没有看到 1 秒的等待,事实上,表单启动时根本没有任何感知延迟。
所以,我看到这个:
现在,我正在使用屏幕转 gif,它以每秒 15 帧的速度运行,所以你看到的是比在你自己的计算机上这样做“有点”慢的效果和响应时间。
但是,screentogif(我使用的屏幕捕获软件)在我单击鼠标时确实显示一个圆圈。因此,当我双击.exe文件(运行它)时,可以看到鼠标单击“圆圈”从screentogif软件闪烁两次。
现在,我没有计算捕获的视频帧数,但它看起来不超过 1 帧延迟。所以,这至少是 1/15 秒,但实际上很可能更短的时间。
换句话说,我们加载和运行该 .exe 文件的时间不到 1/10 秒......
即使我使用 .net core 创建上述相同的项目,我在这里也看不到也找不到任何可察觉的启动延迟。
所以,我不知道.net有一些很大的延迟或启动时间,而且在启动时间方面,它真的不需要运行任何太大的不同,然后与VB6 .exe的启动时间相比。
我想在非常弱的旧硬件上,VB6 可能会有更好的启动时间,但它不应该非常明显,而且它肯定不在 1-2 秒范围内。对于一个非常大的 .net 应用程序,在首次运行时,您经常会看到延迟,因为该.exe实际上尚未编译为机器代码!!当您构建 .net .exe 时,该 exec 实际上还没有编译的机器代码)。它有所谓的 p 代码(就像 VB5/6 一样)。这个所谓的“IL”代码(中间语言或所谓的“p代码”)尚未编译,并且这种代码编译仅在您第一次运行代码时发生!!因此,.net 有一个 JIT(实时编译器系统),代码会在你使用它时和首次运行时进行编译。但是,正如我所指出的,对于上述简单和小型应用程序,在启动时根本不应该察觉到这种延迟。
而编译只需要发生一次,之后,编译后的代码就会被记住。这与磁盘缓存和程序加载无关 - 它仅特定于用于编译和运行 .exe 文件的 JIT 系统。
这表明这里还有其他一些问题,例如您的病毒软件扫描并阻止 .exe 启动,直到病毒扫描软件可以首先完成对 .exe 文件的检查。
或者,您在此处使用了一些网络共享文件夹,或者您没有与我们共享的其他一些重要细节。
事实上,如上所示,从 Visual Studio 2022 中按 f5 甚至不需要 2 秒!但是按 f5 是完全编译,+ 构建,然后运行。(多个操作,其中一个是用户永远不会看到的)。
因此,通过双击该文件或从命令提示符键入 .exe 文件名来运行从该 VS 项目创建的结果 .exe 文件肯定会启动,并在一秒内运行,更不用说两秒了。
请记住,我是在笔记本电脑上运行的,而不是高端规格的笔记本电脑,更不用说更好、更强大的台式电脑了。
而且,如果我创建一个 .net 核心 winforms .exe,那么再一次,我不会察觉到任何延迟。由于构建,我当然在 .bin 文件夹中看到更多文件,但在使用 .net core 时我没有看到任何变化或加载时间增加。我也许可以尝试冷启动(重新启动),但我怀疑它会有什么不同。
评论
C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe /t:winexe /platform:x86 test.vb
评论