Производительность побитовых операторов в javascript

Одна из основных идей использования побитовых операторов в таких языках, как С++/java/С#, заключается в том, что они очень быстрые. Но я слышал, что в javascript они очень медленные (по общему признанию, несколько миллисекунд, вероятно, сегодня не имеет большого значения). Почему это так?

(этот вопрос обсуждается, когда используются побитовые операторы, поэтому я изменяю фокус этого вопроса на производительность.)

Ответы

Ответ 1

Когда вы хотите их использовать? Вы хотели бы использовать их, если хотите выполнять побитовые операции. Так же, как вы должны использовать логические операторы для выполнения логических операций и математических операторов для выполнения математических операций.

Если вам удобно работать с побитовыми операторами, очень естественно использовать их для некоторых приложений. Они могут использоваться для многих целей, кроме избыточного оптимизированного логического массива. Конечно, эти обстоятельства не очень часто возникают в программировании Javascript, но нет причин, по которым операторы не должны быть доступны.

Ответ 2

Это довольно старый вопрос, но никто не ответил на обновленную версию.

Эффект, который вы получаете с JavaScript, который не существует в C/С++, - это отличное от плавающего объекта (как JavaScript все его номера) к 32-битовому целому числу для выполнения манипуляции бит и обратно.

Ответ 3

Никто больше не использует hex?

function hextoRgb(c) {
    c = '0x' + c.substring(1);
    return [(c >> 16) & 255, (c >> 8) & 255, c & 255]; 
}

var c1 = hextoRgb('#191970');
alert('rgb(' + c1.join(',') + ')');

Ответ 4

Я использую побитовый сдвиг нуля в JS для выполнения быстрого целочисленного усечения:

var i=3.141532;
var iTrunc=i>>0; //3

Ответ 5

Существует эмулятор NES, написанный на JavaScript - кажется, что он использует множество поразрядных операций.

Ответ 7

Я бы подумал, что разработчик должен сделать оператор эффективным или неэффективным. Например, нет ничего, что помешало бы разработчику JavaScript создавать JITting VM, который превращает побитовое op в 1 машинную инструкцию. Таким образом, нет ничего по своей сути замедлять "побитовые операторы в JavaScript".

Ответ 8

Я сомневаюсь, что побитовая операция особенно медленна в javascript. Так как такие операции могут отображаться непосредственно в операциях ЦП, которые сами по себе являются достаточно эффективными, , похоже, не существует какой-либо неотъемлемой характеристики побитовых операций, которые заставили бы их быть нерегулярно медленными в javascript.
Редактировать декабрь 2015: Я стою исправлено! Производительность, которую Javascript терпит в отношении поразрядных операций, связана с необходимостью преобразования из float в int и обратно (поскольку все числовые переменные в Javascript хранятся как значения с плавающей запятой). Спасибо Чаду Шуггинсу за указание на это.

Тем не менее, как указано в нескольких ответах, существуют различные приложения javascript, которые полагаются на побитовую работу (например: crytography and graphics) и которые не особенно медленны... (см. Шелковистый и Snarfblam на этой странице). Это говорит о том, что в то время как медленнее, чем C/С++ и другие языки, которые транслируют напрямую побитовые операции с отдельными командами CPU, побитовые операции все вялые.

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

Несмотря на то, что javascript использовался для других целей, наиболее распространенное использование этого языка при предоставлении типов пользовательского интерфейса.
Кстати, я не имею в виду это ни в каком уничижительном отношении; выполнение этих умных функций пользовательского интерфейса и рассмотрение различных ограничений, налагаемых на язык, а также неудовлетворительное соблюдение стандартов, потребовало - и продолжает требовать талантливых хакеров. Дело в том, что в контексте требований типа UI потребность в любом количестве побитовых операций, подверженных воздействию медленности javascript при обработке таких операций, в лучшем случае встречается редко. Следовательно, для типичных применений программисты должны использовать побитовые операции, где и если этот подход, похоже, хорошо работает с общей программой/данными, и они должны делать это, не заботясь о проблемах с производительностью. В маловероятном случае производительности узкое место, возникающее из-за поразрядного использования, всегда можно реорганизовать вещи, но лучше избавиться от ранней оптимизации.

Заметным исключением из этого является введение canvas в современных браузерах, мы можем ожидать, что для javascript-хостов потребуются более примитивные графические функции, и в некоторых случаях такие операции могут потребоваться тяжелые дозы побитовых операций (а также здоровые математические функции). Вполне вероятно, что в конечном итоге эти службы будут поддерживаться с помощью javascript-библиотек (и даже в конечном итоге в качестве языковых дополнений). Для таких библиотек общие принципы отрасли будут использованы для определения наиболее эффективных подходов. Более того, и если есть слабость в работе javascript с побитовыми операциями, мы получим некоторую помощь, поскольку я предсказываю, что реализация javascript на разных узлах (браузерах) будет изменена для улучшения этой конкретной области. (Это будет следовать типичной схеме эволюции javascript, которую мы видели на протяжении многих лет.)

Ответ 9

Люди делают интересные вещи в JavaScript.

Например, в нем реализовано множество криптографических алгоритмов (по разным причинам); поэтому, конечно, используются побитовые операторы.

Ответ 10

Использование JavaScript в воплощении Java JScript для сценариев Windows может привести к использованию побитовых операторов для выбора флагов в значениях, возвращаемых из вызовов WMI или Active Directory. Например, значение пользовательского доступа для пользовательской записи в AD содержит несколько флагов, упакованных в одно длинное целое.

ADS_UF_ACCOUNTDISABLE = 0x00000002;

if (uac & ADS_UF_ACCOUNTDISABLE == ADS_UF_ACCOUNTDISABLE) {
  // user account has been disabled
}

Или какая-то произвольная структура таблицы может содержать такое поле, доступное через ADO с JScript.

Или вы можете конвертировать некоторые извлеченные данные в двоичное представление на любой платформе только потому, что:

BinaryData = "L";
BinaryString = BinToStr(BinaryData, ".", "x");

// BinaryString => '.x..xx..'

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

Ответ 11

Когда скорость имеет первостепенное значение, вы можете использовать их для маскировки бит: http://snook.ca/archives/javascript/storing_values/

Кроме того, если вам нужно поддерживать Netscape 4, вы должны использовать их для работы с Document.captureEvents(). Не то, чтобы какая-нибудь уважаемая компания хотела написать JS для NS4...

Ответ 12

Здесь сравнивается множество побитовых операций: http://jsperf.com/rounding-numbers-down/3

Однако не стесняйтесь создавать свой собственный тестовый тест производительности на jsPerf!