Производительность побитовых операторов в JavaScript - PullRequest
18 голосов
/ 06 октября 2009

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

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

Ответы [ 12 ]

18 голосов
/ 22 июня 2012

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

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

15 голосов
/ 06 октября 2009

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

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(',') + ')');
8 голосов
/ 06 октября 2009

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

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

8 голосов
/ 06 октября 2009

Я использую побитовое смещение нуля в JS, чтобы выполнить быстрое целочисленное усечение:

var i=3.141532;
var iTrunc=i>>0; //3
5 голосов
/ 06 октября 2009

Я нашел хорошую информацию @ http://dreaminginjavascript.wordpress.com/2009/02/09/bitwise-byte-foolish/

Видимо, они очень хорошо работают в наши дни. Зачем тебе их использовать? По той же причине, что и везде.

4 голосов
/ 06 октября 2009

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

2 голосов
/ 06 октября 2009

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

1 голос
/ 06 октября 2009

Используя JavaScript в своем воплощении JScript для Windows Scripting Host, у вас может возникнуть необходимость использовать побитовые операторы для выбора флагов в значениях, возвращаемых из вызовов 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. Что касается производительности, единственный способ узнать это написать и протестировать. Я подозреваю, что в большинстве случаев это было бы совершенно приемлемо, не намного хуже, чем любая другая из множества неэффективностей, которые содержат эти системы.

1 голос
/ 06 октября 2009

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

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

1 голос
/ 06 октября 2009

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

Тем не менее, как указано в нескольких ответах, существуют различные приложения javascript, которые используют побитовую работу (например, криптография и графика) и которые не особенно медленны ... (см. Silky и Snarfblam на этой странице). Это говорит о том, что, хотя медленнее, чем C / C ++ и другие языки, которые переводят напрямую побитовые операции в одиночные собственные инструкции ЦП, побитовые операции - все это вялое.

Давайте тем не менее развлечем возможность того, что по каким-то конкретным причинам различные исполнители хостов javascript реализовали побитовые операции таким способом, который делает их чрезвычайно медленными, и посмотрим, имеет ли это значение ...

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

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

...