2012-12-06 33 views
9

我聽說在發佈模式下編譯生成優化的代碼比調試模式,這很好。編譯發佈和調試將生成不同的IL代碼+不同的機器代碼?

但是,這是IL的優化?一旦CLR運行它,它是否在機器代碼中?是與Release和Debug中編譯的PE不同的元數據結構?

感謝

+0

好問題,但你爲什麼想知道? – Cameron

+2

因爲我在求職面試中被拒絕而生氣。我認爲我們的開發人員應該更多地瞭解幕後的工作方式 – RollRoll

+0

偉大的問題! – nawfal

回答

14

構建Release版本會打開C#編譯器的/ optimize編譯選項。這有一個幾個副作用,IL確實改變,但不是很多。值得注意的是,編譯器不再努力使代碼完美可調試。例如,它跳過一個空的靜態構造函數,它不再發出NOP操作碼,它允許您在大括號中設置斷點並允許具有不同範圍的局部變量在棧幀中重疊。小東西。

最重要的區別是爲程序集發出的[Debuggable]屬性,其IsJITOptimizerDisabled屬性爲false。

這打開了真正的優化器,這是內置於抖動中的優化器。您可以在this answer中找到它執行的優化列表。請注意這種方法的有用性,任何語言都有益於代碼優化器在抖動中而不是在編譯器中。

所以簡而言之,IL中的非常小的變化,生成的機器代碼中的非常大的變化。

+2

真棒的答案。 – RollRoll

3

是的,有在IL一些優化 - 特別是調試版本將包括NOP指令很容易讓一個調試器插入破發點,我相信。在提供的調試信息級別(行號等)方面也存在潛在的差異。

我建議你拿一個小樣本程序,用兩種方式編譯它,然後看看ildasm的輸出。

C#編譯器不會做優化 - JIT編譯器做了大部分的是 - 但我認爲有一些差異

+0

謝謝,您是否需要知道元數據結構是否因編譯模式而異? – RollRoll

+0

@EdwinSoho:它仍然是*格式*。這真的取決於你的「結構」是什麼意思。 –

1

cil不同,它被優化。由於機器碼是cil的翻譯,因此它也有所不同。你可以自己看到它,只需在Visual Studio中打開反彙編窗口即可。元數據應該保持不變,因爲您不會更改版本之間的類合同結構。

0

在VB中,編輯+繼續支持的副作用編譯到可執行文件中,這可能導致內存泄漏。它受到WithEvents關鍵字聲明的任何事件的影響。 WeakReference跟蹤這些事件實例。問題是,如果您在沒有調試器的情況下運行應用程序,那些WeakReference會泄漏。進程消耗內存的速率高度依賴於創建類的多少個實例。每個對象每個事件泄漏16個字節。

免責聲明:從漢斯的答案here

this Microsoft knowledge base article複製。

0

這不是確切問題的答案。只需補充一點,您可以通過預處理器標記,有目的地標記哪些代碼必須在調試模式下運行,哪些代碼在發佈模式下運行。

#if DEBUG 
    // code only meant for debug mode 
#endif 

#if NOT DEBUG 
    // code only meant for release mode 
#endif 

所以,如果你這樣做,你會得到不同的IL生成。

相關問題