Булевы против Int в Javascript - PullRequest
       47

Булевы против Int в Javascript

18 голосов
/ 28 августа 2011

Я всегда предполагал, что логические значения были более эффективными, чем целочисленные значения при хранении значения включения / выключения - учитывая, что это является причиной их существования. Недавно я решил проверить, так ли это с помощью jsperf, и это дало противоположные результаты!

http://jsperf.com/bool-vs-int

Вот первый тест, который я попробовал. Переключение значения двухпозиционного переключателя. В Chrome это значительно быстрее, используя 1/0, но в Firefox это немного быстрее, используя bool. Интересно.

http://jsperf.com/bool-vs-int-2

И вот второй тест, который я попробовал. Использование их в условно. Похоже, что это дает существенное преимущество для целых, по сравнению с bools, до 70% быстрее использовать 1/0 вместо логических значений - как для Firefox, так и для Chrome. Wtf

Я предполагаю, что мой вопрос, я делаю что-то не так? Почему интс намного лучше в булевой работе? Единственная ценность использования bools ясности, или я упускаю что-то важное?

Ответы [ 4 ]

17 голосов
/ 28 августа 2011

Отказ от ответственности, я могу говорить только за Firefox, но я думаю, что Chrome похож.

Первый пример (http://jsperf.com/bool-vs-int):

  1. Не работает JägerMonkey (метод JavaScript Spidmonkey) вначале включает проверку на логическое значение, а затем просто на xors, что очень быстро (мы не знаем тип a / b, поэтому нам нужно проверить тип). Вторая проверка для int, поэтому, если a / b будет int, это будет немного медленнее. код

  2. Операция вычитания. Мы снова не знаем тип c / d. И снова вам повезло, что мы собираемся принять интеты и вставить это в первую очередь. Но поскольку в JavaScript числовые операции определены как удвоенные значения IEEE 754, нам необходимо проверить наличие переполнения. Таким образом, единственное отличие - это «sub» и «условный переход» при переполнении по сравнению с простым xor в случае 1. код

Второй пример: (Я не уверен на 100% в этом, потому что я никогда не смотрел этот код раньше)

  1. и 3. If . Мы встроили проверку на логическое значение, во всех остальных случаях вызывается функция, преобразующая значение в логическое значение. код

  2. Сравнение и если . Это действительно сложный случай с точки зрения реализации, потому что было действительно важно оптимизировать операции равенства. Так что я думаю, что нашел правильный код, который, кажется, предлагает сначала проверить на двойные, а затем на целые числа. И поскольку мы знаем, что результат сравнения всегда является логическим, мы можем оптимизировать оператор if. код

Продолжение Я сбросил сгенерированный машинный код, так что если вы все еще заинтересованы, здесь вы идете .

В целом, это всего лишь часть более широкой картины. Если бы мы знали, какой тип имеют переменные, и знали, что вычитание не будет переполнено, мы могли бы сделать все эти случаи примерно одинаково быстрыми. Эти усилия предпринимаются с помощью коленчатого вала IonMonkey или v8. Это означает, что вам следует избегать оптимизации на основе этой информации, потому что:

  1. это уже довольно быстро
  2. разработчики движка позаботятся о том, чтобы оптимизировать его для вас
  3. это будет еще быстрее в будущем.
0 голосов
/ 28 августа 2011

Я не знаю, но во втором тесте это делает
if(a) bluh();
против
if(c == 1) bluh();

возможно c==1 быстрее, потому что вы сравниваете значение с тем же типом
но если вы делаете if(a), тогда js нужно проверить, оценивается ли значение как истинное, а не только, если оно истинно ...

Это может быть причиной ...

Может быть, нам нужно проверить
if(c==1)
против
if(a===true) с тремя =

0 голосов
/ 28 августа 2011

Для меня выбор будет основан на использовании API. Всегда возвращайте то, что наиболее полезно. Если бы я использовал вторичный код, я бы предпочел методы, которые возвращают логические значения. Это, вероятно, делает код готовым для цепочки. Альтернатива - предоставить перегруженные методы.

0 голосов
/ 28 августа 2011

ваш тест немного отклонился из-за определения «function» и «var» и вызова функции.Стоимость определения функции и переменных и их вызова будет отличаться от двигателя к двигателю.Я изменил ваши тесты, попробуйте перезапустить браузер (обратите внимание, что IE был выключен, потому что первый запуск был странным, но последовательные запуски были ожидаемыми там, где bool самый быстрый): http://jsperf.com/bool-vs-int-2/4

...