Diğer cevaplardaki çözümlere baktığımda performans için kötü olduğunu bildiğim bazı şeyler gördüm. Onları bir yoruma ekleyecektim ama karşılaştırmalı değerlendirmenin ve sonuçları paylaşmanın daha iyi olduğunu düşündüm. Kendiniz test edebilirsiniz . Aşağıda, her tarayıcıdaki en hızlı işlemden sonra normalleştirilmiş sonuçlarım (ymmv) (ms cinsinden mutlak zamanı elde etmek için 1.0 zamanı normalleştirilmiş değerle çarpın).
Chrome Firefox Opera MSIE Safari Düğümü
-------------------------------------------------- -----------------
1.0 zaman 37ms 73ms 68ms 184ms 73ms 21ms
if-instant 1.0 1.0 1.0 2.6 1.0 1.0
if-dolaylı 1.2 1.8 3.3 3.8 2.6 1.0
Anında Açılma 2.0 1.1 2.0 1.0 2.8 1.3
anahtarlama aralığı 38,1 10,6 2,6 7,3 20,9 10,4
anahtar aralığı2 31,9 8,3 2,0 4,5 9,5 6,9
anahtar-dolaylı dizi 35,2 9,6 4,2 5,5 10,7 8,6
dizi-doğrusal-anahtar 3.6 4.1 4.5 10.0 4.7 2.7
dizi-ikili-anahtar 7.8 6.7 9.5 16.0 15.0 4.9
Windows 7 32bit'te aşağıdaki sürümlerle gerçekleştirildiği yerleri test edin: Chrome 21.0.1180.89m , Firefox 15.0 , Opera 12.02 , MSIE 9.0.8112 , Safari 5.1.7 . Windows için Node.js'de zamanlayıcı çözünürlüğü 1ms yerine 10ms olduğu için düğüm bir Linux 64bit kutusunda çalıştırıldı.
if-acil
Bu hariç tüm test ortamlarda en hızlı, ... drumroll MSIE! (sürpriz sürpriz). Uygulamanın önerilen yolu budur.
if (val < 1000) { /*do something */ } else
if (val < 2000) { /*do something */ } else
...
if (val < 30000) { /*do something */ } else
if-dolaylı
Bu bir çeşididir switch-indirect-array
fakat if
daha hızlı daha yerine -statements ve gerçekleştirir switch-indirect-array
neredeyse tüm test ortamlarında.
values=[
1000, 2000, ... 30000
];
if (val < values[0]) { /* do something */ } else
if (val < values[1]) { /* do something */ } else
...
if (val < values[29]) { /* do something */ } else
anahtar-acil
Bu, test edilen tüm ortamlarda oldukça hızlıdır ve aslında MSIE'deki en hızlısıdır. Bir dizin almak için bir hesaplama yapabildiğinizde çalışır.
switch (Math.floor(val/1000)) {
case 0: /* do something */ break;
case 1: /* do something */ break;
...
case 29: /* do something */ break;
}
Açma aralığı
Bu, Opera'nın dışında yaklaşık bir buçuk kat daha uzun sürdüğü test edilen tüm ortamlardaki en hızlıdan 6 ila 40 kat daha yavaştır. Yavaştır, çünkü motor her durum için değeri iki kez karşılaştırmak zorundadır. Şaşırtıcı bir şekilde Chrome'un Chrome'daki en hızlı işleme kıyasla bunu tamamlaması yaklaşık 40 kat daha uzun sürerken, MSIE yalnızca 6 kat daha uzun sürüyor. Ancak gerçek zaman farkı 1337 ms'de MSIE lehine sadece 74 ms idi (!).
switch (true) {
case (0 <= val && val < 1000): /* do something */ break;
case (1000 <= val && val < 2000): /* do something */ break;
...
case (29000 <= val && val < 30000): /* do something */ break;
}
anahtar-aralık2
Bu bir varyanttır, switch-range
ancak vaka başına sadece bir karşılaştırma ve bu nedenle Opera hariç daha hızlı, ancak yine de çok yavaştır. Vaka deyiminin sırası önemlidir, çünkü motor her vakayı kaynak kod sırası ECMAScript262'de test edecektir : 5 12.11
switch (true) {
case (val < 1000): /* do something */ break;
case (val < 2000): /* do something */ break;
...
case (val < 30000): /* do something */ break;
}
Anahtar-dolaylı dizi
Bu varyantta aralıklar bir dizide saklanır. Bu, test edilen tüm ortamlarda yavaş ve Chrome'da çok yavaş.
values=[1000, 2000 ... 29000, 30000];
switch(true) {
case (val < values[0]): /* do something */ break;
case (val < values[1]): /* do something */ break;
...
case (val < values[29]): /* do something */ break;
}
dizi doğrusal arama
Bu, bir dizideki değerlerin doğrusal aramasının ve switch ifadesinin sabit değerlerle birleşimidir. Birinin bunu kullanmak isteyebilmesinin nedeni, çalışma zamanına kadar değerlerin bilinmemesidir. Test edilen her ortamda yavaştır ve MSIE'de yaklaşık 10 kat daha uzun sürer.
values=[1000, 2000 ... 29000, 30000];
for (sidx=0, slen=values.length; sidx < slen; ++sidx) {
if (val < values[sidx]) break;
}
switch (sidx) {
case 0: /* do something */ break;
case 1: /* do something */ break;
...
case 29: /* do something */ break;
}
Dizi-ikili-anahtar
Bu, array-linear-switch
ikili arama içeren bir varyanttır . Ne yazık ki doğrusal aramadan daha yavaştır. Uygulamam mı yoksa doğrusal arama daha mı optimize edilmiş mi bilmiyorum. Anahtar boşluğunun küçük olması da olabilir.
values=[0, 1000, 2000 ... 29000, 30000];
while(range) {
range = Math.floor( (smax - smin) / 2 );
sidx = smin + range;
if ( val < values[sidx] ) { smax = sidx; } else { smin = sidx; }
}
switch (sidx) {
case 0: /* do something */ break;
...
case 29: /* do something */ break;
}
Sonuç
Performans önemliyse, if
-statements veya switch
anlık değerlerle kullanın.