問題

以下哪一種表現最好?

我看到在JavaScript中實現的方法2具有巨大的效能提高,但是,我無法測量C#中的任何增益,並且想知道編譯器是否已經執行了方法2,即使編寫如方法1.

方法 2 背後的理論是程式碼在每次迭代時都不必訪問 DataTable.Rows.Count,它可以簡單地訪問 int c。

方法1

 for (int i = 0; i < DataTable.Rows.Count; i++) {
    // Do Something
}
 

方法2

 for (int i = 0, c = DataTable.Rows.Count; i < c; i++) {
    // Do Something
}
 

  最佳答案

不,它不能這樣做,因為沒有辦法隨著時間的推移表達一個值的常數。

如果編譯器應該能夠做到這一點,那麼程式碼必須保證返回值為常數的值,並且在迴圈的持續時間內不會發生變化。

但是,在這種情況下,您可以自由地將新行新增到資料表中作為迴圈的一部分,因此,按照您已經完成的方式,您應該做到這一點。

簡而言之,如果 end-index 是變數以外的任何東西,編譯器就不會這樣做。

在變數的情況下,編譯器只能檢視loop-code並看到這個特定變數沒有更改,它可能會這樣做,並在啟動迴圈之前將值載入到暫存器中,但是這樣做的任何效能增益都很可能微不足道,除非迴圈體是空的.

結論:如果您知道或願意接受,在迴圈的持續時間內,終端迴圈索引是常數,將其放入變數中。


編輯:重讀您的帖子,是的,您也可能看到兩種情況的效能增益微不足道,因為JITter優化了程式碼. JITter可能最佳化讀取到包含行計數的資料表中的變數的直接訪問中的內容索引,並且記憶體讀取不是那麼昂貴.另一方面,如果讀取該屬性是一個非常昂貴的操作,則會看到更明顯的區別.

  相同標籤的其他問題

c#performanceloops