.Net 4.0 应用程序在 64 位上比 32 位慢(分析和可能的解决方案)(应用程序正在使用 NetAdvantag



我们用VB .NET 4.0/VS2010编写了.NET应用程序,编译时所有项目都设置为调试和发布配置的AnyCPU设置。我们注意到,当此应用程序在 64 位环境(在 Windows Server 2003 R2 和 2008 R2 上测试)运行时,该应用程序至少需要两倍的时间(绝对值约为 25 秒),而不是在 32 位环境(Win XP 和 7)上大约需要 6-12 秒才能启动。

我应该补充一点,64 位系统是功能强大的服务器,绝对比其他经过测试的 32 位系统更强大。所有其他应用程序在 64 位上都更快,但我们糟糕的应用程序;)(我们确实在不同的时间、不同的负载下测试了应用程序,结果总是几乎相同。

如上所述,该应用程序是使用 AnyCPU 构建的,它确实在 64 位操作系统下作为 64 位程序集运行(通过任务管理器检查)。该应用程序本身是一个WinForms应用程序,利用NetAdvantage Forms v10.3,并定期查询和写入MS SQL Server 2008。

不同的目标机器都在同一个网络上,因此数据库的路径(用于性能测试的相同数据库)是相同的,我认为问题不在于数据库或网络本身。

我确实注意到的一件事对我来说似乎很奇怪,那就是当我在 MainForm 启动期间使用秒表构建不同的"分析步骤"时,InitializeComponent 方法在 64 位上花费了两倍的时间,大约 4 秒,而不是 1.5 位在 32 位上。

这是我们在两个系统上部署的相同应用程序,没有不同的配置。

所以我有两个问题:

知道这可能是什么原因吗?

并且:确定"有问题"的代码段的最佳方法是什么?目前,我使用秒表并尝试缩小范围。但在我看来,就我们的应用程序而言,64 位机器上的所有内容都变慢了,所以我不太确定我可以将其分解为特定的语句。

感谢大家的帮助,非常感谢...

事实证明,一旦我们从编译从 AnyCPU 切换到特定的 x86,即在 x64 位平台上也以 x86 运行,我们又回到了我们的"好速度"。

有同样的问题 - 是的,JIT 是罪魁祸首。 通过明智地使用 msgbox,将其缩小到需要 10 秒才能启动的方法(通过在调用大型方法之前调用消息框,然后作为大型函数的第一行。 而且,是的,只有在编译为 AnyCPU 时才会看到这一点,但在显式 x86 时没有看到这一点;而不是在调试中运行时。

就我而言,这是一个 5000 行的 Windows 窗体InitializeComponent

为了证明这一点,运行(提升)"c:windows<.net framework dir>ngen.exe install <myassembly.exe>",这将编译一个本机映像。 如果这解决了它,那么是的,JIT 是罪魁祸首。

长期修复,要么:

  • 每次部署程序时都使用 NGEN 重建本机映像(或 NGEN 更新重建,但显然只在安装一次后有效); (缺点是管理 ngen 映像和 ngen 所需的时间。 这是我采取的路线,因为大型应用程序的整体性能得到了提升。

  • 或者,可以将属性<System.Runtime.CompilerServices.MethodImpl(MethodImplOptions.NoOptimization)>添加到方法中。 (禁用方法上的 JIT,因此执行速度较慢,但您无需支付 JITing 的初始开销,这对我们来说是昂贵的部分)

(我怀疑两者都是徒劳的,因为这意味着放弃大型方法的原生形象而没有任何收益。

我最近在应用程序中遇到了同样的性能问题。是的,将其编译为 x86 解决了问题;然后它在任一平台上快速运行。但启动响应时间缓慢的真正原因是由于 32 到 64 位迁移问题。我认为,当应用程序启动并经过 JIT 过程将代码转换为 IL 时,编译器正在确定代码中存在问题(如非类型安全代码),在它可以在 64 位模式下运行之前必须解决这些问题。我遇到了这篇文章,现在正在尝试浏览该应用程序以确定哪些部分导致了问题。请参阅本文:http://msdn.microsoft.com/en-us/library/ms973190.aspx。 我可以不管它,因为它可以工作,但理想情况下,如果问题得到解决,它会在 64 位模式下运行得更好。

相关内容