Ketika saya melihat solusi di jawaban lain saya melihat beberapa hal yang saya tahu buruk untuk kinerja. Saya akan memberi mereka komentar tetapi saya pikir lebih baik untuk membandingkannya dan membagikan hasilnya. Anda bisa mengujinya sendiri . Di bawah ini adalah hasil saya (ymmv) dinormalisasi setelah operasi tercepat di setiap browser (kalikan waktu 1.0 dengan nilai dinormalisasi untuk mendapatkan waktu absolut dalam ms).
Chrome Firefox Opera MSIE Safari Node
-------------------------------------------------- -----------------
1.0 waktu 37ms 73ms 68ms 184ms 73ms 21ms
jika-segera 1.0 1.0 1.0 2.6 1.0 1.0
jika-tidak langsung 1.2 1.8 3.3 3.8 2.6 1.0
switch-direct 2.0 1.1 2.0 1.0 2.8 1.3
saklar-kisaran 38.1 10.6 2.6 7.3 20.9 10.4
switch-range2 31.9 8.3 2.0 4.5 9.5 6.9
switch-indirect-array 35.2 9.6 4.2 5.5 10.7 8.6
array-linear-switch 3.6 4.1 4.5 10.0 4.7 2.7
array-binary-switch 7.8 6.7 9.5 16.0 15.0 4.9
Tes di mana dilakukan pada Windows 7 32bit dengan versi berikut: Chrome 21.0.1180.89m , Firefox 15.0 , Opera 12.02 , MSIE 9.0.8112 , Safari 5.1.7 . Node dijalankan pada Linux 64bit box karena resolusi timer pada Node.js untuk Windows adalah 10ms, bukan 1ms.
jika-langsung
Ini adalah yang tercepat di semua lingkungan yang diuji, kecuali di ... drumroll MSIE! (kejutan kejutan). Ini adalah cara yang disarankan untuk mengimplementasikannya.
if (val < 1000) { /*do something */ } else
if (val < 2000) { /*do something */ } else
...
if (val < 30000) { /*do something */ } else
jika-tidak langsung
Ini adalah varian dari switch-indirect-array
tetapi dengan- if
pernyataan sebagai gantinya dan berkinerja lebih cepat daripada switch-indirect-array
di hampir semua lingkungan yang diuji.
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
beralih-langsung
Ini cukup cepat di semua lingkungan yang diuji, dan sebenarnya yang tercepat di MSIE. Ini berfungsi ketika Anda bisa melakukan perhitungan untuk mendapatkan indeks.
switch (Math.floor(val/1000)) {
case 0: /* do something */ break;
case 1: /* do something */ break;
...
case 29: /* do something */ break;
}
saklar-rentang
Ini sekitar 6 hingga 40 kali lebih lambat daripada yang tercepat di semua lingkungan yang diuji kecuali untuk Opera yang membutuhkan waktu sekitar satu setengah kali. Ini lambat karena mesin harus membandingkan nilai dua kali untuk setiap kasus. Anehnya, Chrome membutuhkan waktu hampir 40 kali lebih lama untuk menyelesaikannya dibandingkan dengan operasi tercepat di Chrome, sedangkan MSIE hanya membutuhkan waktu 6 kali lebih lama. Tetapi perbedaan waktu aktual hanya 74ms mendukung MSIE di 1337ms (!).
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;
}
saklar-range2
Ini adalah varian switch-range
tetapi dengan hanya satu perbandingan per case dan karena itu lebih cepat, tetapi masih sangat lambat kecuali di Opera. Urutan pernyataan kasus penting karena mesin akan menguji setiap kasus dalam urutan kode sumber ECMAScript262: 5 12.11
switch (true) {
case (val < 1000): /* do something */ break;
case (val < 2000): /* do something */ break;
...
case (val < 30000): /* do something */ break;
}
switch-tidak langsung-array
Dalam varian ini rentang disimpan dalam array. Ini lambat di semua lingkungan yang diuji dan sangat lambat di Chrome.
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;
}
array-linear-search
Ini adalah kombinasi dari pencarian linear nilai-nilai dalam array, dan pernyataan switch dengan nilai-nilai tetap. Alasan seseorang mungkin ingin menggunakan ini adalah ketika nilai tidak diketahui sampai runtime. Ini lambat di setiap lingkungan yang diuji, dan memakan waktu hampir 10 kali lebih lama dalam MSIE.
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;
}
array-binary-switch
Ini adalah varian array-linear-switch
tetapi dengan pencarian biner. Sayangnya ini lebih lambat daripada pencarian linear. Saya tidak tahu apakah ini implementasi saya atau apakah pencarian linier lebih dioptimalkan. Bisa juga bahwa keyspace adalah ke kecil.
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;
}
Kesimpulan
Jika kinerja penting, gunakan if
pernyataan-atau switch
dengan nilai langsung.