Оптимизация кода JavaScript для использования целочисленной арифметики

Существуют некоторые алгоритмы, которые решают задачи "очень хорошо" в предположении, что "очень хорошо" означает минимизацию количества арифметических операций с плавающей запятой в пользу целочисленной арифметики. Возьмем, например , алгоритм линий Брезенхэма для определения, какие пиксели нужно заполнить, чтобы нарисовать линию на холсте: парень сделал практически весь процесс выполнимым, используя лишь простую целочисленную арифметику.

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

3 ответа

Решение

На самом деле, это не отличается. В JavaScript нет понятия "целое число". JS использует только числа с плавающей запятой двойной точности, которые могут быть или не быть целыми числами.

Следовательно, с точки зрения производительности абсолютно нечего увеличивать, ограничивая себя целыми числами.

Однако имейте в виду, что целые числа будут точными до 251, тогда как нецелые могут очень легко пострадать от потери точности (пример: 0,1), поэтому вы можете получить из-за этого.

Вы можете использовать Int8, Uint8, Int16 и т. Д. В javascript, но это требует немного больше усилий, чем обычно - см. TypedArrays.

var A = new Uint32Array(new ArrayBuffer(4*n));
var B = new Uint32Array(new ArrayBuffer(4*n));

//assign some example values to A
for(var i=0;i<n;i++)
  A[i] = i; //note RHS is implicitly converted to uint32

//assign some example values to B
for(var i=0;i<n;i++)
  B[i] = 4*i+3;  //again, note RHS is implicitly converted to uint32   

//this is true integer arithmetic
for(var i=0;i<n;i++)
  A[i] += B[i]; 

Недавно проект asm.js позволил скомпилировать код C/C++ в странно выглядящий javascript, который использует эти TypedArrays довольно экстремальным образом, преимущество в том, что вы можете использовать существующий код C/C++, и он должен работать довольно быстро в браузере (особенно, если производители браузеров внедряют специальные оптимизации для этого вида кода, что должно произойти в ближайшее время).

На заметку * если вы можете программировать SIMD-параллелизм (см. Википеду), т.е. если ваш код использует набор инструкций SSEx, ваша арифметика будет намного быстрее, и на самом деле использование int8 будет в два раза быстрее, чем использование int16 и т. Д.

* Я не думаю, что это актуально для браузеров, потому что им слишком сложно пользоваться на лету. Изменить: Оказывается, что Firefox экспериментирует с этим видом оптимизации. Также Dart (истинный Dart, а не Dart, скомпилированный в js) сможет сделать это в Chrome.

Давным-давно компьютерам не хватало выделенных FPU, и они делали математику с плавающей запятой полностью посредством программной эмуляции.

Все современные компьютеры имеют специальные FPU, которые обрабатывают математические вычисления с плавающей запятой так же хорошо, как и целые числа. Вам не нужно беспокоиться об этом, если у вас нет особых обстоятельств.

Другие вопросы по тегам