Boolean vs Int в Javascript
Я всегда считал, что булевы были более эффективными, чем ints при хранении значения on/off - учитывая, что их причина существования. Недавно я решил проверить, верно ли это с помощью jsperf, и он придумал некоторые противоположные результаты!
http://jsperf.com/bool-vs-int
Вот первый тест, который я пробовал. Переключение значения включения/выключения. В Chrome это значительно быстрее сделать с помощью 1/0, но в firefox это немного быстрее, чтобы сделать это с помощью bool. Интересно.
http://jsperf.com/bool-vs-int-2
И вот второй тест, который я пробовал. Использование их в условном выражении. Это, как представляется, имеет существенное преимущество для int, а не для bools, до 70% быстрее использовать 1/0 вместо логических - как для Firefox, так и для хром. Wtf?
Я думаю, мой вопрос в том, что я делаю что-то неправильно? Почему ints намного лучше при булевой работе? Единственное значение использования ясности bools, или я пропущу что-то важное?
Ответы
Ответ 1
Отказ от ответственности, я могу говорить только для Firefox, но я думаю, что Chrome похож.
Первый пример (http://jsperf.com/bool-vs-int):
-
Не работает
JägerMonkey (метод spidmonkey JavaScript methodjit) строит проверку для булевых сначала, а затем просто xors, что очень быстро (мы не знаем тип a/b, поэтому нам нужно проверить тип).
Вторая проверка выполняется для int, поэтому, если a/b будет int, это будет немного медленнее.
Код
-
Операция вычитания.
Мы снова не знаем тип c/d. И снова вам повезло, что мы сначала возьмем ints и inline. Но поскольку в JavaScript число операций указано как удвоение IEEE 754, нам нужно проверить переполнение. Таким образом, единственное различие - "под" и "условный переход" при переполнении против простого xor в случае 1.
Код
Второй пример:
(Я не уверен на 100%, потому что я никогда не смотрел этот код раньше)
-
и 3. Если.
Мы встраиваем проверку для boolean, все остальные случаи в конечном итоге вызывают функцию, преобразующую значение в логическое.
Код
-
Сравнение и.
Это очень сложный случай с точки зрения реализации, потому что было действительно важно оптимизировать операции равенства. Поэтому я думаю, что нашел правильный код, который, кажется, предлагает сначала проверить двойное, а затем на целые числа.
И поскольку мы знаем, что результат сравнения всегда является логическим, мы можем оптимизировать оператор if
.
Код
Followup Я сбросил сгенерированный машинный код, поэтому, если вас все еще интересует, здесь вы идете.
В целом это всего лишь кусок в увеличенной картине. Если бы мы знали, какой тип переменных имел и знали, что вычитание не будет переполняться, мы могли бы сделать все эти случаи одинаково быстрыми.
Эти усилия предпринимаются с помощью IonMonkey или v8 коленчатого вала. Это означает, что вам следует избегать оптимизации на основе этой информации, потому что:
- он уже довольно быстро
- разработчики двигателей позаботятся об оптимизации для вас
- он будет еще быстрее в будущем.
Ответ 2
ваш тест был немного отключен из-за определения "function" и "var" и вызова функции. Стоимость определения функции и переменных и их вызов будут отличаться от движка к движку. Я изменил ваши тесты, попытаюсь повторно запустить с вашими браузерами (обратите внимание, что IE был отключен, потому что первый запуск был странным, но последовательные прогоны были такими, как ожидалось, где bool является самым быстрым): http://jsperf.com/bool-vs-int-2/4
Ответ 3
Я не знаю, но во втором тесте он делает
if(a) bluh();
против
if(c == 1) bluh();
может быть c==1
быстрее, потому что вы сравниваете значение с одним с тем же типом
но если вы делаете if(a)
, тогда js нужно проверить, соответствует ли значение true, а не только если оно истинно...
Это может быть причиной...
Возможно, нам нужно протестировать
if(c==1)
против
if(a===true)
с тремя =
Ответ 4
Для меня выбор будет основан на использовании API. Всегда возвращайте то, что наиболее полезно. Если я использую вторичный код, я бы предпочел методы, возвращающие логические значения. Это, вероятно, делает код готовым к цепочке. Альтернативой является предоставление перегруженных методов.