Перемикач Javascript порівняно, якщо… інше, якщо… інше


143

Хлопці, у мене є кілька питань:

  1. Чи є різниця в продуктивності JavaScript між switchоператором та an if...else?
  2. Якщо так, чому?
  3. Чи поведінка switchтаif...else різні веб-переглядачі? (FireFox, IE, Chrome, Opera, Safari)

Причиною задавати це питання є те, що я маю кращу ефективність у switchзаяві з приблизно 1000-ти випадками у Firefox.


Відредаговано На жаль це не мій код, 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] = ім'я передано у функцію сервера

Тепер я змінив висновок функції, яку потрібно вставити в TextArea, написав код JavaScript для розбору через функцію та перетворив її на набір case операторів.

нарешті, я запускаю функцію, і вона працює нормально, але продуктивність відрізняється в IE і Firefox.


1
Я б запропонував зразок коду, щоб вивчити, що оптимально. Я маю на увазі, має бути причина, що ви це просите, правда?
jcolebrand

Будь ласка, опублікуйте те, що ви збираєтесь, тому що в моєму багаторічному досвіді дуже мало випадків, для яких я б сказав, що заява про перемикання у 100 випадках або 100-частина, якщо / else серія була гарною ідеєю.
Поні

Вибачте, хлопці не за 100, а за тисячі умов
Джон Харцок

2
Всім, дякую за внесок. Але моя проблема не була насправді різницею між if і swith. Це був код, що працює всередині оператора. +1 усім вам за допомогу. Вибачте за незручності. Іноді вам просто потрібно поговорити з іншою людиною, щоб знайти рішення.
Джон Хартсок

Відповіді:


113

Відповіді в загальних рисах:

  1. Так, зазвичай.
  2. Більше інформації тут
  3. Так, оскільки у кожного є інший двигун обробки JS, однак, виконуючи тест на нижньому веб-сайті, перемикач завжди виконував функцію if, інакше якщо велика кількість ітерацій.

Тестовий майданчик


1
Якщо ви хочете TLDR про те, коли використовувати які умови тут, це пряме посилання на сегмент у статті, на який йдеться
edhedges

2
@Tommy Гарна стаття, дякую за обмін. Однак у статті зазначено, що в JS існує незначна різниця між показниками switchта if/thenтвердженнями. У статті зазначено, що це пов'язано з плямистою switchоптимізацією та різними способами функціонування різних двигунів JS. Цитата:Since most JavaScript engines don’t have such optimizations, performance of the switch statement is mixed.
Джаспер

3
Чи є в цьому описі щось кількісно вимірюване? Він читає як багато гіпотез про "кращі практики / передчасна оптимізація". Це також було написано 7 років тому, тому оптимізація JavaScript надзвичайно змінилася за цей час. У складених мовах різниця в продуктивності між цими трьома операціями "майже ніколи не є достатньо істотною для того, щоб дбати". Не турбуйтеся оптимізувати речі, які не впливатимуть на фактичну ефективність. Оптимізуйте читабельність.
Thomson Comer

3
@Tommy « Більше інформації тут » дає 404, що там було?
LogicDaemon

2
@LogicDaemon - IIRC - це посилання на деякі текстові скриньки oRielly, які потрапили в якісь невмілі міркування / дискусії щодо виконання JS
Tommy

61

Іноді краще не використовувати жодного. Наприклад, у ситуації "відправки" 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", але перевага (коли є багато випадків) пошуку хешу для пошуку функції для конкретного ключа.


2
Ваша стратегія хороша, і я її часто використовую. Але , як зазначив на @Michael Гирі stackoverflow.com/a/45336805/5936119 , змінна карта повинна бути оголошена поза контекстом відправки в іншому випадку вона завжди буде повторно оцінити.
Даніель Сантана

@DanielSantana правда, але я сумніваюся, що це значно дорого. Зокрема, після того, як функція спочатку розбирається, код не потребує відновлення, оскільки текст є статичним.
Понтій

18

Різниця в продуктивності між a switchі if...else if...elseневелика, вони в основному виконують ту саму роботу. Одна з різниць між ними, яка може змінити, полягає в тому, що вираз для тестування оцінюється лише раз у той switchчас, як він оцінюється для кожного if. Якщо оцінити вираз досить дорого, це робити один раз, звичайно, швидше, ніж робити це в сто разів.

Різниця в реалізації цих команд (і всього сценарію в цілому) різниться між браузерами. Як правило, в різних браузерах спостерігаються досить великі відмінності в продуктивності одного і того ж коду.

Оскільки ви навряд чи зможете перевірити ефективність усіх кодів у всіх браузерах, вам слід шукати код, який найкраще підходить для того, що ви робите, і намагатися зменшити обсяг виконаної роботи, а не оптимізувати, як це робиться.


7
  1. Якщо є різниця, вона ніколи не буде достатньо великою, щоб її помітили.
  2. Н / З
  3. Ні, всі вони функціонують однаково.

В основному, використовувати все, що робить код найбільш читабельним. Однозначно є місця, де одна чи інша конструкція робить більш чистими, читабельнішими та більш ретельними. Це набагато важливіше, що можливо збереження декількох наносекунд у коді JavaScript.


5
Особливо в javascript, семантика та читабельність (а отже, ремонтопридатність) перетворюють будь-які локалізовані відмінності в продуктивності між if..elseта switchспричиненими унікальним комп'ютерним обладнанням версії браузера та комбінацією ОС.
джебл

2
Я не знаю, чи погоджуюсь, це справді можна помітити, якщо він використовується в циклі з, скажімо, великою базою даних, обхід дерева тощо
ghoppe

2
я точно не згоден. Оскільки веб-додатки стають все складнішими, ця різниця може бути істотною для програми та може змінюватися залежно від браузерів.
joshvermaire

7
Важливо - писати чистий, підтримуваний код. Коли видно проблему з продуктивністю - профіль. Потім визначте, який код виправити. Не жертвуйте ремонтом для припущених проблем з продуктивністю.
Джон Бенедікто

3
'якщо інше, якщо інше ...' є O (n), тоді як 'switch' є або O (1), або O (log (n)). Як ви можете чесно заявити, що різниця ніколи не може бути достатньо великою? Вмикайте мільйон випадків (це легко можливо, якщо код генерується), і ви, безумовно, помітите його як мінімум.
драконя

6

Крім синтаксису, перемикач може бути реалізований за допомогою дерева, яке створює його O(log n), тоді як if / else має бути реалізований з O(n)процедурним підходом. Частіше вони обидва обробляються процедурно, і різниця полягає лише в синтаксисі, і більше того, чи це насправді має значення - хіба ви статистично набираєте 10k випадків if / else все одно?


Через 7 років ... Я не бачу, як можлива реалізація дерева, за винятком випадків постійних числових значень регістра).
Ед Штауб

4

Відповідь Пойні пропонує використовувати об'єкт-буквал як альтернативу switchабо if/ 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();
}

3

Чи є різниця у форматі Javascript між оператором перемикання та параметром if ... else if .... else?

Я не думаю, що switchце корисно / коротко, якщо ви хочете запобігти численні if-elseумови.

Чи поведінка перемикача і якщо ... інше, якщо ... інше відрізняється в браузерах? (FireFox, IE, Chrome, Opera, Safari)

Поведінка однакова у всіх браузерах :)


5
switch is useful/short if you want prevent multiple if-else conditions.Так, сер, чудовий пост.
NiCk Newman

1
  1. Workbenching може призвести до дуже невеликих відмінностей у деяких випадках, але спосіб обробки в будь-якому випадку залежить від браузера, тому не варто турбуватися
  2. Через різні способи обробки
  3. Ви не можете назвати його веб-переглядачем, якщо поведінка все одно відрізнятиметься

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.