在.NET平台裡,大部分編譯器的最佳化並不是通過VB和C#編譯器來完成的。它們寧可把最佳化的處理推後到CLR的即時(Just In Time,JIT)編譯器讀取IL,並轉換為原生機器碼的時候來完成。由於這個原因,對JIT的改變會極大地影響之前編譯好的程式集。
一個主要的影響就是內嵌函式(Inlining Function)調用。之前,JIT對內聯方法的處理非常保守,Vance Morrison解釋了個中緣由,
它對內聯的處理並不是很好。內聯總是減少指令執行的數量(這是由於最低限度的調用和返回指令沒有被執行),但是它能(並經常)讓結果代碼變得很大。大部分人都能直覺地理解,內聯大的方法(比如1Kb的)不是很有意義,而內聯非常小的方法可以讓調用的佔用空間更小(由於調用指令才5位元組),這樣的選擇總是正確的,但是介於兩者之間的方法要如何處理呢?
有趣的是,當你讓代碼變大時,你也就讓它執行緩慢,因為記憶體天生地緩慢;你的代碼越大,它越不會放在最快的CPU緩衝(稱之為L1)裡面執行,在那樣的情況下,處理器需要執行3-10個周期直到它能從另外的緩衝(稱之為L2)中擷取到執行代碼,如果L2緩衝中還不存在,那麼就需要到主記憶體中擷取(需要花費10+周期)。對於在緊密迴圈中執行的代碼,這樣的結果不會有什麼問題,因為所有的代碼都適合放入到最快緩衝中(典型的是64K),不過對於“常規的”代碼,它通過大量的方法來執行大量的代碼,“越大就越慢”的效果就非常顯著。更大的代碼也就意味著在啟動時從磁碟擷取代碼需要更大的磁碟I/O,這就意味著你的應用程式啟動較慢。
在Service Pack 1中,微軟引入了一個新的基於代碼尺寸的啟發學習法演算法,來判斷調用是否處於一個迴圈中。在常規情況下,函數只有當在調用空間中的結果機器碼比原始版本要小時,才能被內聯。這樣做就保證了儘可能多的代碼能適合CPU的緩衝,當緩衝不夠用時,就能對效能產生巨大的影響。
當處在迴圈中時,分部異常也可以很好地工作。這是因為據推測函數通常會被多次調用,所以CLR允許內嵌函式可以增長至原始調用大小的5倍大。類似實值型別最佳化這樣的條件有可能更進一步地增加容許尺寸的大小。