Мне дали задачу портирования Java Java.util.Random()
к JavaScript, и я натыкался на огромный хит/погрешность производительности с помощью побитовых операторов в JavaScript на достаточно больших количествах. Некоторое поверхностное исследование указывает, что "побитовые операторы в JavaScript являются по сути медленными", потому что внутренне кажется, что JavaScript бросит все свои двойные значения в 32-разрядные целые числа со знаком, чтобы сделать битовые операции (см. здесь для больше на этом.) Из-за этого, я не могу сделать порта для прямого обращения генератора случайных чисел Java, и я должен получить те же числовые результаты как Java.util.Random()
. Запись чего-то как
this.next = function(bits) {
if (!bits) {
bits = 48;
}
this.seed = (this.seed * 25214903917 + 11) & ((1 << 48) - 1);
return this.seed >>> (48 - bits);
};
(который является почти-портом-для-прямого-обращения Java.util.Random()
) код не будет работать правильно, так как JavaScript не может сделать битовых операций на целом числе тот размер.)
Я выяснил, что могу просто сделать seedable генератор случайных чисел в 32-разрядном пространстве с помощью алгоритма Lehmer, но прием - то, что я должен получить те же значения, как я был бы с Java.util.Random()
. Что я должен сделать для создания более быстрого, функционального порта?
Альтернативой является использование логического массива из 48 логических значений и самостоятельная реализация сдвига. Однако я не знаю, быстрее ли это; но я сомневаюсь в этом, поскольку все логические значения хранятся как двойные.
Вместо foo & ((1 << 48) - 1)
вы должны иметь возможность использовать foo% Math .pow (2,48)
.
Все числа в Javascript - это 64-битные числа с плавающей запятой, которых достаточно для представления любого 48-битного целого числа.
Имейте в виду, что битовый сдвиг прямо эквивалентен умножение или деление на степень 2.
1 << x == 1 * Math.pow(2,x)
Это медленнее, чем битовый сдвиг, но позволяет расширяться за пределы 32 бит. Это может быть более быстрым решением для бит> 32
, если учесть дополнительный код, необходимый для поддержки большего числа битов, но вам придется провести некоторое профилирование, чтобы выяснить .
48-битные побитовые операции в JavaScript невозможны. Однако вы можете использовать два числа, чтобы смоделировать это.