Dot-Net

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

  • December 9, 2014

我們有用 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 位上花費的時間是 64 位的兩倍,大約 4 秒,而 1.5在 32 位上。

這是我們在兩個系統上部署的完全相同的應用程序,沒有不同的配置。

所以我有兩個問題:

知道這可能是什麼原因嗎?

並且:確定“違規”程式碼的最佳方法是什麼?目前我使用秒錶並嘗試縮小範圍。但在我看來,就我們的應用程序而言,64 位機器上的一切都比較慢,所以我不太確定是否可以將其分解為特定的語句。

謝謝大家的幫助,非常感謝…

事實證明,一旦我們從 AnyCPU 編譯切換到專門的 x86,即也在 x64 位平台上作為 x86 執行,我們又回到了“良好的速度”。

有同樣的問題 - 是的,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 的初始成本,這對我們來說是昂貴的部分)

(我懷疑兩者都做是徒勞的,因為這意味著放棄大型方法的原生形象而沒有收穫。)

引用自:https://stackoverflow.com/questions/12979774