2010-05-27 92 views
95

傢伙,我有幾個問題:的Javascript開關主場迎戰如果...否則,如果...否則

  1. 是否有switch語句和if...else之間在JavaScript的性能差異?
  2. 如果是這樣,爲什麼?
  3. switch行爲和跨瀏覽器if...else不同? (FireFox,IE,Chrome,Opera,Safari)

問這個問題的原因似乎是,我在Firefox的約1000個案例中的switch聲明中獲得了更好的性能。


編輯 Unfortuantly這不是我的代碼JavaScript是正在生產服務器端從編譯的庫,我要的代碼的訪問權限。正在生產的JavaScript的方法被稱爲

CreateConditionals(string name, string arrayofvalues, string arrayofActions) 

arrayofvalues是一個逗號分隔的列表。

它所產生的是

function [name] (value) { 
    if (value == [value from array index x]) { 
    [action from array index x] 
    } 
} 

注:其中[name] =傳遞到服務器端功能

現在我改變了函數的輸出要插入一個文本區的名字,寫了一些JavaScript代碼通過函數解析,並將其轉換爲一組case語句。

最後我執行此功能,它運行良好,但性能在IE和Firefox不同。

+1

我會建議一個代碼示例來檢查哪些是最佳的。我的意思是,你有這個問題的理由,對吧? – jcolebrand 2010-05-27 16:34:57

+0

請發表您的評論,因爲在我長期的經歷中,我很少會遇到這樣的情況,我會說100個開關語句或100個部分的if/else系列是個好主意。 – Pointy 2010-05-27 16:40:54

+0

對不起,你們不是100幾歲,而是成千上萬的條件 – 2010-05-27 17:04:42

回答

74

接聽泛泛:

  1. 是的,平常LY。
  2. See More Info Here
  3. 是的,因爲每個人都有不同的JS處理引擎,但是,在下面的網站上運行測試時,交換機總是在大量迭代中執行if,elseif。

Test site

+0

感謝tommy您的示例網站在嘗試確定if和switch之間的性能差異時很好用。它非常小,它使我得出結論,我的問題在其他地方,正如我在對我的問題發表評論時指出的那樣。謝謝你的時間。 – 2010-05-27 17:36:53

+1

+1非常有趣的文章 – Martin 2012-08-09 18:57:33

+1

如果你想的時候這裏使用的條件語句一個TLDR是直接鏈接到段的文章在解決:http://oreilly.com/server-administration/excerpts/even-faster -websites /寫高效,javascript.html#the_fastest_conditionals – edhedges 2013-05-06 13:43:37

3

是否有一個switch語句 並且如果之間 JavaScript中的性能與區別...如果還有別的....?

我不這麼認爲,switch是有用/短,如果你想防止多個if-else條件。

是開關的行爲,並 如果...否則,如果...跨瀏覽器 什麼不同呢? (火狐,IE瀏覽器,鉻,歌劇,Safari瀏覽器 )

行爲是相同的所有瀏覽器:)

+2

'如果你想防止多個if-else條件,'switch是有用/短的.'是的,先生,偉大的職位。 – 2015-07-14 02:55:27

6
  1. 如果是有區別的,它永遠不會大到足以被注意到。
  2. N/A
  3. 不,它們的功能完全相同。

基本上,使用任何使代碼最具可讀性的代碼。確實有一個或其他結構可以使清潔,更易讀和更易維護。這更重要,可能會在JavaScript代碼中節省幾納秒。

+4

特別是在javascript中,語義和可讀性(以及可維護性)勝過由唯一瀏覽器版本計算機硬件和操作系統組合導致的'if..else'和'switch'之間的任何本地化性能差異。 – jball 2010-05-27 16:40:21

+1

我不知道我是否同意,它可能確實被注意到,如果它被用於循環與說,一個大型數據庫,遍歷樹等 – ghoppe 2010-05-27 16:50:47

+1

我絕對不同意。隨着Web應用程序變得越來越複雜,這種差異可能對應用程序有重大意義,並可能依賴於瀏覽器而改變。 – joshvermaire 2011-11-22 23:52:17

1
  1. Workbenching可能導致在某些情況下,一些非常小的差異,但處理的方式是依賴於瀏覽器反正太不值得費心
  2. 由於處理
  3. 不同的方式,你不能把它的瀏覽器,如果該行爲會有所不同,無論如何
6

除了語法,一個開關可以用一棵樹,這使得它O(log n)來實現,而的if/else必須與O(n)程序的方法來實現。更經常地,它們都是程序處理的,唯一的區別就是語法,而且它真的很重要 - 除非靜態地輸入10k個if/else的case嗎?

+0

7年後......我沒有看到樹實現是如何實現的,除了在數值常量值不變的情況下)。 – 2017-02-11 15:03:02

49

有時候最好不要使用。例如,在「調度」的情況下,JavaScript允許你在一個完全不同的方式做的事情:

function dispatch(funCode) { 
    var map = { 
    'explode': function() { 
     prepExplosive(); 
     if (flammable()) issueWarning(); 
     doExplode(); 
    }, 

    'hibernate': function() { 
     if (status() == 'sleeping') return; 
     // ... I can't keep making this stuff up 
    }, 
    // ... 
    }; 

    var thisFun = map[funCode]; 
    if (thisFun) thisFun(); 
} 

設置多路通過創建一個對象分支有很大的優勢。您可以動態添加和刪除功能。您可以從數據創建調度表。你可以通過編程來檢查它。您可以使用其他函數構建處理程序。

有一個函數調用獲得「case」的等價物的額外開銷,但是有一個散列查找的優點(當有大量情況時)爲特定的鍵查找函數。

13

switchif...else if...else之間的性能差異很小,它們基本上做了同樣的工作。他們之間可能有差異的一個區別是,要測試的表達式僅在switch中評估一次,而對每個if進行評估。如果評估這個表達的代價是昂貴的,那麼這樣做一次當然要比做一百次更快。

這些命令(以及所有腳本一般)的實現差異在瀏覽器之間有很大不同。在不同的瀏覽器中看到相同的代碼有相當大的性能差異是很常見的。

正如你很難性能測試在所有瀏覽器所有的代碼,你應該去那個最適合你在做什麼的代碼,並儘量減少工作的完成,而不是優化它是如何做的量。

0

Pointy's answer建議使用對象常量來替代switchif/else的。我喜歡這種方法太多,但在回答的代碼創建一個新map對象每次dispatch函數調用時:

function dispatch(funCode) { 
    var map = { 
    'explode': function() { 
     prepExplosive(); 
     if (flammable()) issueWarning(); 
     doExplode(); 
    }, 

    'hibernate': function() { 
     if (status() == 'sleeping') return; 
     // ... I can't keep making this stuff up 
    }, 
    // ... 
    }; 

    var thisFun = map[funCode]; 
    if (thisFun) thisFun(); 
} 

如果map包含了大量條目,這可以創造顯著的開銷。最好只設置一次動作地圖,然後每次使用已經創建的地圖,例如:

var actions = { 
    'explode': function() { 
     prepExplosive(); 
     if(flammable()) issueWarning(); 
     doExplode(); 
    }, 

    'hibernate': function() { 
     if(status() == 'sleeping') return; 
     // ... I can't keep making this stuff up 
    }, 
    // ... 
}; 

function dispatch(name) { 
    var action = actions[name]; 
    if(action) action(); 
}