簡體   English   中英

局部變量或類字段?

[英]Local variables or class fields?

我今天讀了一篇關於 C#和Java 性能改進文章

我還是堅持這個:


19.不要過度使用實例變量

使用局部變量可以提高性能。 示例1中的代碼執行速度比示例2中的代碼快。

例1:

public void loop() {
    int j = 0;
    for ( int i = 0; i<250000;i++){
        j = j + 1;
    }
}

例2:

int i;
public void loop() {
    int j = 0;
    for (i = 0; i<250000;i++){
        j = j + 1;
    }
}

實際上,我不明白為什么在我可以對字段進行簡單訪問時,每次調用loop函數時實例化一些內存並釋放它應該更快。

這是純粹的好奇心,我不是試圖將變量'i'放在類的范圍內:p是否真的使用局部變量更快? 或者只是在某些情況下?

  1. 比堆更快堆棧。

     void f() { int x = 123; // <- located in stack } int x; // <- located in heap void f() { x = 123 } 
  2. 不要忘記地方數據的原則 應該在CPU緩存中更好地緩存本地數據。 如果數據接近,它們將完全加載到CPU緩存中,並且CPU不必從內存中獲取它們。

性能低至獲取變量所需的步驟數。 本地變量地址在編譯時是已知的(它們是堆棧上的已知偏移量),用於訪問加載對象“this”的成員以獲取實際對象的地址,然后才能獲取成員變量的地址。

即使它會,但在這種情況下幾乎沒有可衡量的差異。 Probabbly在第一種情況下,有一些優化的處理器注冊表層面完成,但再次:

  • 這幾乎無關緊要
  • 更重要的是,往往是不可預測的。

在記憶方面,它完全相同 ,沒有任何區別。

第一種情況它通常更好:當你聲明變量時,它是立即使用的,這是常用的良好模式,因為它是

  • 易於理解(職責范圍)
  • 簡單的重構

在C#中,另一個細微差別是生成的MSIL指令的數量(我猜它在Java中類似)。

加載實例字段需要兩條指令:

ldarg.0                 // load "this" reference onto stack
ldfld   MyClass.myField // find the field and load its value

...但只需要一條指令來加載局部變量:

ldloc.0                 // load the value at index 0 from the list of local variables

我懷疑差異很小,但是在變量是對象成員的情況下,每次訪問都需要通過this (有效)進行間接,而局部變量則不需要。

更一般地說,對象不需要成員i ,它只在循環的上下文中使用,因此在任何情況下使其在本地使用都更好。

我測試了500,000次迭代的計算,其中我在本地使用了大約20個變量,並且使用了字段。 局部變量測試大約是20毫秒,帶有字段的測試大約是30毫秒。 使用局部變量時,性能顯着提高。

性能差異是否相關,取決於項目。 在您的平均業務應用程序中,性能增益可能不明顯,最好是可讀/可維護代碼,但我正在開發聲音合成軟件,其中像這樣的納米優化實際上變得相關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM