JavaScript之條件表示式效能影響?

使用if-else或者switch的流行理論是基於測試條件的數量:條件數量較大,傾向於使用switch而不是if-else。這通常歸結到程式碼的易讀性。

方法/步驟

一、if-else

大多數情況下switch表示式比if-else更快,但只有當條件體數量很大時才明顯更快。兩者間的主要效能區別在於:當條件體增加時,if-else 效能負擔增加的程度比switch 更多。因此,我們的自然傾向認為條件體較少時應使用if-else 而條件體較多時應使用switch 表示式,如果從效能方面考慮也是正確的。

一般來說,if-else 適用於判斷兩個離散的值或者判斷幾個不同的值域。如果判斷多於兩個離散值,switch表示式將是更理想的選擇。

二、優化if-else

優化if-else 的目標總是最小化找到正確分支之前所判斷條件體的數量。最簡單的優化方法是將最常見的條件體放在首位。

if-else中的條件體應當總是按照從最大概率到最小概率的順序排列,以保證理論執行速度最快。

三、查表法

有些情況下要避免使用if-else或switch。當有大量離散值需要測試時,if-else和switch都比使用查表法要慢得多。在JavaScript中查表法可使用陣列或者普通物件實現,查表法訪問資料比if-else或者switch更快,特別當條件體的數目很大時。

與if-else和switch相比,查表法不僅非常快,而且當需要測試的離散值數量非常大時,也有助於保持程式碼的可讀性。例如,當switch 表示式很大時就變得很笨重,諸如:

switch(value){

case 0:

return result0;

case 1:

return result1;

case 2:

return result2;

······

case 9:

return result9;

default:

return result10;

}

switch 表示式程式碼所佔的空間可能與它的重要性不成比例。整個結構可以用一個數組查表替代:

var results = [result0,······ result9, result10]

return results[value];

當使用查表法時,必須完全消除所有條件判斷。操作轉換成一個數組項查詢或者一個物件成員查詢。使用查表法的一個主要優點是:由於沒有條件判斷,當候選值數量增加時,很少,甚至沒有增加額外的效能開銷。

查表法最常用於一個鍵和一個值形成邏輯對映的領域(如前面的例子)。一個switch 表示式更適合於每個鍵需要一個獨特的動作,或者一系列動作的場合。

四、呼叫棧限制

JavaScript 引擎所支援的遞迴數量與JavaScript 呼叫棧大小直接相關。只有Internet Explorer 例外,它的呼叫棧與可用系統記憶體相關,其他瀏覽器有固定的呼叫棧限制。大多數現代瀏覽器的呼叫棧尺寸比老式瀏覽器要大(例如Safari 2 呼叫棧尺寸是100)。當你使用了太多的遞迴,超過最大呼叫棧尺寸時,瀏覽器會出錯並彈出以下資訊:

1、Internet Explorer: “Stack overflow at line x”

2、Firefox: “Too much www.heyzc.com recursion”

3、Safari: “Maximum call stack size exceeded”

4、Opera: “Abort (control stack overflow)”

Chrome 是唯一不顯示呼叫棧溢位錯誤的瀏覽器。

關於呼叫棧溢位錯誤,最令人感興趣的部分大概是:在某些瀏覽器中,他們的確是JavaScript錯誤,可以用一個try-catch表示式捕獲。異常型別因瀏覽器而不同。在Firefox中,它是一個InternalError;在Safari和Chrome中,它是一個RangeError;在Internet Explorer中丟擲一個一般性的Error 型別。(Opera不丟擲錯誤;它終止JavaScript 引擎)。這使得我們能夠在JavaScript中正確處理這些錯誤:

try {

recurse();

} catch (ex){

alert("Too much recursion!");

}

如果不管它,那麼這些錯誤將像其他錯誤一樣冒泡上傳(在Firefox中,它結束於Firebug和錯誤終端;在Safari/Chrome中它顯示在JavaScript終端上),只有Internet Explorer例外。IE 不會顯示一個JavaScript錯誤,但是會彈出一個提示堆疊溢位資訊的對話方塊。

相關問題答案