Коли я подивився на рішення в інших відповідях, я побачив деякі речі, які, на мою думку, погані для роботи. Я збирався викласти їх у коментар, але я подумав, що краще порівняти його та поділитися результатами. Ви можете перевірити його самостійно . Нижче мої результати (ymmv) нормалізуються після найшвидшої роботи в кожному браузері (помножте 1,0 раз на нормоване значення, щоб отримати абсолютний час у мс).
Сафарі-вузол Chrome Firefox Opera MSIE
-------------------------------------------------- -----------------
1,0 час 37ms 73ms 68ms 184ms 73ms 21ms
if-безпосередній 1,0 1,0 1,0 2,6 1,0 1,0
якщо-непрямі 1,2 1,8 3,3 3,8 2,6 1,0
перемикач-негайний 2.0 1.1 2.0 1.0 2.8 1.3
діапазон комутаторів 38,1 10,6 2,6 7,3 20,9 10,4
перемикач-діапазон2 31,9 8,3 2,0 4,5 9,5 6,9
перемикач-непрямий масив 35,2 9,6 4,2 5,5 10,7 8,6
масив-лінійний комутатор 3.6 4.1 4.5 10.0 4.7 2.7
масив-бінарний комутатор 7,8 6,7 9,5 16,0 15,0 4,9
Тест, який виконується на Windows 7 32bit з наступними версіями: Chrome 21.0.1180.89m , Firefox 15.0 , Opera 12.02 , MSIE 9.0.8112 , Safari 5.1.7 . Node запускався на 64-бітній коробці Linux, оскільки роздільна здатність таймера для Node.js для Windows становила 10 мс замість 1 мс.
якщо-негайний
Це найшвидший у всіх перевірених середовищах, за винятком ... MSD ! (здивування, здивування). Це рекомендований спосіб його реалізації.
if (val < 1000) { /*do something */ } else
if (val < 2000) { /*do something */ } else
...
if (val < 30000) { /*do something */ } else
якщо-непрямий
Це варіант, switch-indirect-array
але if
замість-заяв замість цього працює набагато швидше, ніж switch-indirect-array
майже у всіх перевірених середовищах.
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
перемикач-негайний
Це досить швидко у всіх перевірених середовищах і насправді найшвидше в MSIE. Він працює, коли ви можете зробити розрахунок, щоб отримати індекс.
switch (Math.floor(val/1000)) {
case 0: /* do something */ break;
case 1: /* do something */ break;
...
case 29: /* do something */ break;
}
перемикач-діапазон
Це приблизно в 6 - 40 разів повільніше, ніж найшвидший у всіх перевірених умовах, за винятком Opera, де це займає близько півтора разів. Це повільно, оскільки двигун повинен порівнювати значення вдвічі для кожного випадку. Дивно, але Chrome потребує майже 40 разів довше, щоб виконати це порівняно з найшвидшою роботою в Chrome, тоді як MSIE займає лише 6 разів. Але фактична різниця у часі становила лише 74 мс на користь MSIE у 1337 мс (!).
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;
}
комутатор-діапазон2
Це варіант, switch-range
але лише з одним порівнянням на випадок, і тому швидше, але все ще дуже повільно, за винятком Opera. Порядок викладу справи важливий, оскільки двигун перевірятиме кожен випадок у порядку вихідного коду ECMAScript262: 5 12.11
switch (true) {
case (val < 1000): /* do something */ break;
case (val < 2000): /* do something */ break;
...
case (val < 30000): /* do something */ break;
}
перемикач-непрямий масив
У цьому варіанті діапазони зберігаються в масиві. Це повільно в усіх перевірених середовищах і дуже повільно в 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;
}
масив-лінійний-пошук
Це комбінація лінійного пошуку значень у масиві та оператора перемикання із фіксованими значеннями. Причина, з якою можна скористатися цим, полягає в тому, що значення не відомі до часу виконання. Він повільний у кожному тестованому середовищі і займає майже 10 разів довше в 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
Це варіант, array-linear-switch
але з двійковим пошуком. На жаль, це повільніше, ніж лінійний пошук. Я не знаю, чи це моя реалізація чи лінійний пошук більш оптимізований. Можливо також, що клавіша мала.
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;
}
Висновок
Якщо продуктивність важлива, використовуйте if
твердження або switch
з негайними значеннями.