8

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

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

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

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

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

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

所以我有两个问题:

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

并且:确定“违规”代码的最佳方法是什么?目前我使用秒表并尝试缩小范围。但在我看来,就我们的应用程序而言,64 位机器上的一切都比较慢,所以我不太确定是否可以将其分解为特定的语句。

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

4

3 回答 3

4

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

于 2012-11-20T03:02:05.280 回答
4

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

就我而言,它是一个 5000 行的 Windows Forms InitializeComponent

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

长期修复,或者:

  • 每次部署程序时使用 ngen 来重建本机映像(或使用 ngen update 来重建,但显然只能安装一次);(缺点是管理 ngen 图像和 ngen 所需的时间。这是我采取的路线,因为对于大型应用程序有整体性能提升。)

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

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

于 2014-12-09T20:40:00.697 回答
2

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

于 2014-02-28T17:15:02.490 回答