JavaScript - === vs == производительность операторов
Несколько недель назад я прочитал эту тему <быстрее, чем <=? об операторах сравнения в C
, Было сказано, что нет различий в производительности между <
а также <=
так как они интерпретируются как одинаковые / похожие машинные команды.
В то же время в "лучших практиках" нашей компании говорилось, что мы всегда должны использовать "===" для сравнения, а не "==". Итак, я начал задаваться вопросом, всегда ли это уместно, поскольку я привык использовать "==" и "typeof... ==" и не хочу менять свой способ написания:-]
Обратите внимание, что это в контексте JavaScript.
Итак, у меня есть небольшое исследование, и здесь Какой оператор равенства (== vs ===) должен использоваться в сравнениях JavaScript? он сказал, что:
Это связано с тем, что оператор равенства == выполняет приведение типов... это означает, что интерпретатор неявно пытается преобразовать значения, а затем выполняет сравнение.
С другой стороны, оператор тождества === не приводит к приведению типов, и поэтому он не преобразует значения значений при сравнении
И я начал задаваться вопросом, означает ли это, что когда я использую оператор "===", я получу хорошую производительность, так как никакие ресурсы не будут потрачены на преобразование операндов. И после того, как весь код превращен в машинные команды, означает ли это, что разницы в C
когда вы используете <
а также <=
это то же самое в JavaScript и других языках?
6 ответов
Для js оператор === вернет true, если он используется в строковых типах, а строки имеют одинаковые символы. Для объектов сравниваются ссылки на объекты, а не содержимое.
Из стандарта ECMA:
11.9.6 Алгоритм сравнения строгого равенства Сравнение x === y, где x и y - значения, дает истину или ложь. Такое сравнение выполняется следующим образом:
- Если Type(x) отличается от Type(y), вернуть false.
- Если Тип (x) не определен, вернуть true.
- Если Type(x) равен Null, вернуть true.
- Если Тип (x) является Число, тогда a. Если x равен NaN, вернуть false. б. Если y равен NaN, вернуть false. с. Если x - это то же самое числовое значение, что и y, вернуть true. д. Если x равен +0, а y равен -0, вернуть true. е. Если x равен -0, а y равен +0, вернуть true. е. Вернуть ложь.
- Если Type(x) - String, тогда вернуть true, если x и y - это абсолютно одинаковая последовательность символов (одинаковая длина и одинаковые символы в соответствующих позициях); в противном случае верните false.
- Если Type(x) - логическое значение, вернуть true, если x и y оба - true или оба false;
Я чувствую, что ответ с легко проверяемыми доказательствами будет лучшим.
Эти операции настолько малы, что их сложно протестировать на производительность.
- == 1648 верно
- === 1629 верно
- контрольный тест 1575 верно
Если вы вычли контрольный тест, похоже, что в моем браузере разница в скорости составляет ~30%. Если вы делаете это несколько раз, вы можете получить разные ответы, но === обычно получается быстрее всего, что, я думаю, является лишь свидетельством того, насколько незначительной является разница.
Я думаю, что это в значительной степени подтверждает то, что говорили другие, что разница в производительности - пустая трата времени на размышления, но это также показывает, что === на самом деле быстрее. Надеемся, что этот ответ может сэкономить время других людей, тех, кто просто должен видеть доказательства.
var testString = "42";
var testNumber = 42;
var testObject = {};
var start = Date.now();
var result = null;
for(var i = 0; i < 100000000; i++){
result = testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject &&
testString == testString && testNumber == testNumber && testObject == testObject
}
console.log("==", Date.now() - start, result);
var start = Date.now();
var result = null;
for(var i = 0; i < 100000000; i++){
result = testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject &&
testString === testString && testNumber === testNumber && testObject === testObject
}
console.log("===", Date.now() - start, result);
var start = Date.now();
for(var i = 0; i < 100000000; i++){
result = true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true &&
true && true && true
}
console.log("control test", Date.now() - start, result);
Во-первых, производительность просто не имеет значения. Для любого реального сценария любой выигрыш в производительности при использовании одного оператора над другим будет бесконечно малым по сравнению с другими узкими местами в коде (обычно манипулирование DOM является целью номер один).
Во-вторых, во многих случаях ==
а также ===
будет выполнять точно такие же шаги. Когда типы двух операндов одинаковы (например, две строки или два числа), спецификация ECMAScript имеет одинаковые шаги для двух операторов. Поэтому, если вы наблюдаете разницу в производительности между двумя операторами для операндов одного типа в одном браузере или другой среде, нет никакой гарантии или даже вероятности того, что вы увидите похожую разницу в другом браузере.
В случае typeof
Как уже упоминалось в вашем вопросе, два операнда гарантированно будут одного типа (строка), и оба оператора будут делать одно и то же, поэтому единственными причинами предпочтения одного оператора перед другим являются стилистические.
Сообщество JS в целом пошло довольно жестко по этому вопросу: консенсус, кажется, "никогда не использовать ==
а также !=
если вам не нужно принуждение типа ", что слишком догматично для моих вкусов.
Неважно, какую производительность вы получите, ===
явно лучший выбор в этом случае. Все остальное, например, лучшая производительность - это просто глазурь на торте. Кроме того, разница в любом случае минимальна.
Это язык сценариев. Производительность этих операторов не должна иметь большого значения, так что вам стоит об этом беспокоиться, потому что есть множество других вещей, которые потребляют гораздо больше энергии, например, тот факт, что он работает на виртуальной машине, имеет слабую типизацию и работает с HTML DOM внутри браузера...
Кроме того, оба оператора делают совершенно разные вещи, поэтому один не может быть взаимозаменяемым в любом случае.
Тем не менее, я думаю (но не проверял), что ===
быстрее. Причина в том, что ему нужно только сравнить тип, и, если он совпадает, сравнить необработанные данные. ==
Оператор попытается преобразовать один тип в другой, если они не совпадают. Это будет более дорогая операция в большинстве случаев.
И это удачно, потому что в большинстве случаев ===
это лучший вариант.:)
Но в любом случае вы можете легко протестировать его (убедитесь, что вы тестировали несколько случаев, как с одним, так и с несколькими разными типами), но если вы не знаете, как это проверить, я бы перестал беспокоиться об этом вообще. Разница, если таковая имеется, не убьет вас.
Разница в производительности незначительна, что означает, что вы не должны тратить драгоценные мозговые циклы, думая об этом. Если вы действительно хотите знать, вы должны проверить.
использование ===
если у вас нет веских причин не делать этого (вероятно, нет).