2011-08-19 101 views
5

性能方面,多次直接訪問數組元素還是將其值賦給變量並使用該變量會更好?假設我將在下面的代碼中多次引用該值。直接訪問數組元素與將其分配給變量

這個問題背後的原因是,訪問一個數組元素大概會在每次完成時涉及一些計算成本,而不需要額外的空間。另一方面,將該值存儲在變量中會消除這種訪問成本,但會佔用額外的空間。

// use a variable to store the value 
Temp = ArrayOfValues(0) 
If Temp > 100 Or Temp < 50 Then 
    Dim Blah = Temp 
    ... 

// reference the array element 'directly' 
If ArrayOfValues(0) > 100 Or ArrayOfValues(0) < 50 Then 
    Dim Blah = ArrayOfValues(0) 
    ... 

我知道這是一個簡單的例子,但假設我們在談論在實際使用中在什麼點(其中值將被多次引用)規模較大的空間和計算時間價值之間的權衡考慮(如果有的話)?

+1

優化編譯器將對HLL進行徹底的嘗試。如果您使用匯編或關閉優化,寄存器比緩存更快,所以應儘可能將常用值加載到寄存器中。總的來說,我認爲註冊壓力和內存層次之間的臨界點可能是經驗問題。 – Patrick87

回答

2

內存消耗的開銷非常有限,因爲對於引用類型,它只是一個指針(幾個字節),大多數值類型也只需要幾個字節。

在大多數語言中,數組是非常高效的結構。獲得索引不涉及任何查找,只是一些數學(每個數組插槽需要4個字節,所以第11個插槽位於偏移量40)。然後,邊界檢查可能會有一些開銷。爲新的本地變量分配內存並釋放它需要一些cpu週期。所以最終它還取決於通過複製到本地變量來消除多少個數組查找。

事實是,你真的需要非常糟糕的硬件或者真的有很大的循環,因爲這非常重要,如果它對它進行了體面測試。我個人經常選擇單獨變量,因爲我發現它使代碼更易讀。

你舉的例子是奇數順便說一句,因爲你創建局部變量之前做2個陣列查找:) 這更有意義(排除2個查詢)

Dim blah = ArrayOfValues(0) 
if blah > 100 or blah < 50 then 
... 
2

這是標記語言無關,但我不真的不相信它是。這篇文章回答了問題的C和C++版本。

優化編譯器可以照顧「裸」數組訪問;在C或C++中,如果沒有函數被調用,沒有理由認爲編譯器不記得內存位置的值。例如。

int a = myarray[19]; 
int b = myarray[19] * 5; 
int c = myarray[19]/2; 
int d = myarray[19] + 3; 

但是,如果myArray的不只是定義爲int [],但實際上是一些「花哨」,特別是一些用戶定義的容器類型與另一個轉換單元中定義的函數operator[](),那麼該功能必須是每次請求該值時都會調用該函數(因爲該函數正在返回內存中的位置處的數據,並且本地函數不知道該函數的結果是否意圖保持不變)。儘管如此,即使使用'裸'數組,但如果在函數調用周圍多次訪問同一個東西,編譯器也必須假設該值已被更改(即使它可以記住地址本身)。例如。

int a = myarray[19]; 
NiftyFunction(); 
int b = myarray[19] * 8; 

編譯器無法知道myarray [19]在函數調用之前和之後將具有相同的值。因此,一般來說,如果您知道某個值在本地範圍內是不變的,請將其「緩存」到局部變量中。您可以防守編程和使用斷言來驗證這種情況下,你已經把對事物:

int a = myarray[19]; 
NiftyFunction(); 
assert(myarray[19] == a); 
int b = a * 8; 

最後一個好處是,它更容易在調試器來檢查的值,如果他們不陣列中的某處埋藏。

+1

+1「這是標記的語言不可知論者,但我並不真的相信它。」 C#答案在某些方面可能會有所不同,但我沒有資格提供它。 – ClickRick

相關問題