部署时,便携版和win-x64有什么区别?

51

我将我的代码部署到 Windows Server 2016 上的 IIS,并尝试了解在发布/设置/目标运行时下拉菜单中选择 Portable 与 win-x64 的实际差异。

在 Portable 下,由于 JIT 需要将代码编译为特定架构,网站启动需要更长时间吗?还有其他方面的影响吗?

enter image description here

3个回答

35

编辑 - 简短回答

如果您选择 portable ,每次启动应用程序时,它都需要对实际执行的应用程序部分进行JIT编译。如果您的应用程序很大,性能可能会受到影响。

如果您选择 x64 ,应用程序不会因为编译而变慢,因为这已经由发布过程在构建机器(您的笔记本电脑)上完成。


原始回答

当您选择Portable发布选项时,您将获得一个可以在x86(32位)机器和x64(64位)机器上运行的包。选择便携式选项后,在应用程序启动时,您将获得针对目标机器(x64或x86)的JIT编译代码,因为应用程序正在运行。但是,如果应用程序关闭,则所有已经JIT编译的代码都将丢失。编译代码存储在内存中,直到应用程序进程结束。下一次运行将再次使用JIT编译应用程序。这里的优点是您只需要分发一个软件包,它将在x86 / x64机器上运行。

另外一种选择是生成多个打包文件,每个针对不同的目标平台。在这种情况下,你将获得专门为各个机器编译好的打包文件,并且甚至在应用程序进程结束并重新启动后也不需要重新编译。这样做会使你的应用程序看起来运行更快,因为编译只会在构建服务器/机器上进行一次。然而,它确实会影响你的部署方式。

关于.NET运行时标识符的更多信息可以在此处找到:https://learn.microsoft.com/en-us/dotnet/core/rid-catalog

有关JIT编译代码的良好文档,请参阅此处:https://www.telerik.com/blogs/understanding-net-just-in-time-compilation


6
我怀疑这一点。即使您使用 win-x64,JIT编译仍应该是执行的一部分。.NET Native目前还不适用于.NET Core,因此没有AOT来取代JIT。 - Lex Li
1
现在有一个新增的复选框选项“启用 ReadyToRun 编译”,似乎更多地涉及到这个回复所说的内容。而这个选项只适用于特定平台的目标。如果未选中它,我不确定目标的区别是什么。 - Jonas
1
这个答案是错误的。JIT编译总是在第一次运行时执行。 - Alex from Jitbit

11

被接受的答案关于JIT假设有点错误(无论如何,JIT编译都会在目标机器上发生)。来自@Greg-Gum的其他答案解释了R2R要求,但仍未解释底层发生了什么。

当您将“目标运行时”设置为“可移植”时,发布过程会在发布目标中包含运行时DLL

发布目标中将有一个/runtime子文件夹,其中包括多个平台及其组合的本地/运行时文件和依赖项。此文件夹可能有几兆字节。

例如:假设您的项目使用SqlClient nuget。在Windows上(但不在Linux上),此nuget依赖于sni.dll本地库。因此,该文件将放置在/runtimes/win-x64/native/sni.dll/runtimes/win-x86/native/sni.dll(相应版本)中。

这只是一个例子,还有许多其他事情正在进行。


2
这个答案比被接受的那个更好。 - Mert Akcakaya
有没有相关的文档可以提供参考? - T.S.

11
接受的答案在Visual Studio 2022已经不再适用。
明显的区别在于一个是可移植的,而另一个是为特定架构设计的。
不那么明显的区别是,当您选择win-x64时,然后可以选择“启用ReadyToRun编译”。
然而,ReadyToRun并不总是意味着更快。 有关详细信息,请参见此处的文档。
简而言之,选择ReadyToRun时,编译器会尽其所能地进行编译,但它没有实际运行机器的具体信息。 因此,文件大小要大得多,多达2-3倍。 文档中的建议是将其用于大型项目,而不是小型项目,但您必须自己决定什么是大型和小型。
我的建议是,如果您预先知道使用的架构,请选择特定的架构。 至于ReadyToRun,如果测试显示它对启动时间有益,则选择它,如果启动时间很重要的话。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接