Вопрос по jquery, javascript, performance – Выполнение операции ИЛИ (||) по сравнению с inArray ()

7

Предположим, что вы хотите проверить, какую строку ввода пользователь ввел в поле формы. Какой из них будет самым быстрым способом проверки этих входных данных по списку возможных значений?

Следующие примеры использованияjQuery.

Первый метод: использование||

<code>if (input == "firstValue" || input == "secondValue" || ... ) {
    ...
}
</code>

Второй метод: использованиеinArray()

<code>if ($.inArray(input, array) >= 0) {
    ...
}
</code>

Есть ли существенные различия между этими двумя методами?

Это действительно JavaScript, о котором вы говорите? Niko
@Niko LOL извините, неправильные теги: D Отредактировано user1301428
оба имеют O (n) сложность в наихудшем случае, где n - количество тестируемых объектов, единственным выигрышем в производительности будет то, что один не вызов функции, а другой -. Andreas Wong
@Niko ~ вероятно, JQuery на самом деле.api.jquery.com/jquery.inarray Richard Neil Ilagan
Однако на практике я склоняюсь к чему-тоinArray() больше только за то, что он имеет больший потенциал быть динамичным для больших наборов данных контрпроверки. А также быть легче читать. Только представьте, было ли у нас 10 или около того значений для контрпроверки! : D Richard Neil Ilagan

Ваш Ответ

4   ответа
4

it depends...

Если есть только несколько возможностей, используйтеif (a || b || c).

Если есть до 10, используйтеArray.indexOf()

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

Если есть (много) больше, используйтеObject с ключами, равными значениям, то вы можете использоватьif (myVar in myKeyObj), Это должно дать в худшем случаеO(log n) спектакль.

@ThiefMaster дох! Так что, это...
@ThiefMaster, почему вы думаете, что это PHP? По тому, что он использует долларовый префикс? :) сказав это, он полагается на логический результат inArray ... чувак, это сбивает с толку
Я отредактировал вопрос, чтобы прояснить, что я использую jQuery. user1301428
Я думаю, что он отметил вопрос неправильно. Его код PHP, а не JavaScript.
O(log n)? Предполагая, что JavaScript использует хеш-таблицу для поиска ключей объекта, это будетO(1)не так ли?
2

function inArray(needle, haystack) {
  for (i = 0; i < length; i++) {
    if (haystack[index] == needle) {
      return true;
    }
  }

  return false;
}

Если бы вы развернули этот цикл, вы бы в конечном итоге сделали

if (haystack[0] == needle) {
  return true;
} 
if (haystack[1] == needle) {
  return true;
}
if (haystack[3] == needle) {
  return true;
}
// and so on

который может быть сжат до

if (haystack[0] == needle || haystack[2] == needle || … ) {
  return true;
}

не меняя происходящего под капотом.

Если вам постоянно приходится искать подобные вещи, я предлагаю вам ознакомиться с картами. вместо

var haystack = ['hello', 'world', 'how', 'is', 'life'];
if (inArray("life", haystack)) {
  // …
}

ты сделаешь

var haystack = {'hello' : true, 'world' : true, 'how' : true, 'is' : true, 'life' : true};
if (haystack["life"]) {
  // …
}

Чем больше элементов нужно проверить, тем лучше будет карта по сравнению с массивом.

jsperf.com/map-or-array показывает, что с 10 элементами inArray () работает быстрее, но с 26 элементами уже медленнее, чем inMap (). Обратите внимание, что производительность inArray () соотносится с количеством элементов в массиве и положением элемента, если он может быть найден. inMap (), с другой стороны, имеет одинаковую производительность независимо от элементов для сравнения.
Я бы почувствовал улучшение производительности, если бы мне нужно было сравнить, скажем, менее 100 элементов? user1301428
Большое спасибо за ваш ответ, теперь все понятно :) user1301428
Хорошо, поэтому Chrome не согласен с Firefox на InArray () с 10 элементами быстрее. В любом случае, вы должны получить изображение & # x2026;
2

avascript, и, как правило, это трудные вопросы.

В этом примере ключевое различие между решениями - масштабирование. Первое решение всегда будет выполнять заранее определенное количество сравнений, решение inArray масштабируется хуже, потому что оно будет сравнивать больше, если есть больше значений.

Тем не менее, я по-прежнему использую InArray, шансы на производительность 99,99% действительно не имеют значения. Вы хотите, чтобы ваш код обслуживался, это важнее.

The first solution will always do a predetermined amount of comparesЯ думал, что javascript / php завершится рано, если это произойдет в любом из||?
@TJHeuvel Макс будет известен? user1301428
Конечно, в зависимости от того, сколько заявлений вы пишете;)
Ааа, теперь я понимаю, что вы подразумеваете подpredetermined, Спасибо
Правда, поэтому максимум будет известен.
17

in_array() (JavaScript:array.indexOf(value) >= 0) для более чем 2 или 3 значений.

Разница в производительности незначительна - хотя вызов функции и создание массива, безусловно, имеют некоторые накладные расходы, это не имеет значения по сравнению с дорогостоящими операциями, такими как доступ к файлам, доступ к базе данных, доступ к сети и т. Д. Поэтому, в конце концов, никто не заметит разницу ,

Вот короткийэталонный тесткаждая с 1 миллионом итераций:

5.4829950332642 - in_array, the array is recreated everytime
2.9785749912262 - in_array, the array is created only once
0.64996600151062 - isset(), the array way created only once and then the values were turned to keys using array_flip()
2.0508298873901 - ||

Итак, самый быстрый, но все же очень читаемый способ это. Если вы не создаете$arr только один раз и использовать егоmany раз в этом нет необходимости, и вы можете просто остаться сin_array().

$arr = array_flip(array('your', 'list', 'of', 'values'));
if(isset($arr[$value])) ...

Если тыdid попросить JavaScript (в этом случаеget rid of those $ prefixes!), лучшее решение используетArray.indexOf():

['a', 'b', 'c'].indexOf(value) >= 0

Однако не все браузеры уже поддерживаютArray.indexOf()так что вы можете использовать, например, функция отUnderscore.js:

_.contains(['a', 'b', 'c'], value)

JQuery также имеет функцию для этого:

$.inArray(value, ['a', 'b', 'c'])

Самый быстрый способ будет с объектом иin оператор, но определение объекта менее читаемо, чем определение массива:

value in {'a':0, 'b':0, 'c':0}

Вот эталонный тест JSPerf для различных решений:http://jsperf.com/inarray-vs-or - но опять же, довольно большая разница в производительности в большинстве случаев незначительна, поскольку вы не собираетесь выполнять код миллионы раз в цикле.

Это действительно хорошая идея, если весь код написан вами и не считается устаревшим кодом - если вы используетеfor(var i in array) где-то (что вы не должны), продолжаяArray.prototype сломать эти петли. Кроме того, OP уже использует jQuery.
Разница в производительности имеет значение только в том случае, если фактическая проверка выполняется много раз, а массив всегда один и тот же, то есть вы можете создать массив один раз, а затем повторно использовать его.
+1 сила короткого, краткого ответа
& quot; Итак, самый быстрый, но все же очень читаемый способ - это. Если вы не создаете $ arr только один раз и используете его много раз, в этом нет необходимости, и вы можете просто остаться с in_array (). & Quot; Можете ли вы объяснить эту часть лучше, пожалуйста? user1301428
ИМХО, лучше шимитьArray.indexOf() чем включить еще одну целую библиотеку JS ...

Похожие вопросы