Pull to refresh

Типизированые массивы

Reading time 2 min
Views 16K
С появлением WebGL появились и несколько новых типов данных, в частности типизированные массивы. Они все обладают похожим интерфейсом и по скорости значительно превосходят обычные массивы, обладают контролем границ и всего двумя методами и одним свойством. На данный момент если я не ошибаюсь то типизированные массивы поддерживаются последними версиями FireFox и Chrome.
Подробнее о типизированных массивах можно почитать в спецификации
Ну, а в статье мы рассмотрим основы основ

Типы типизированных массивов


Таблица украдена из спецификации

Тип Размер в байтах Описание Аналог в C
Int8Array 1 8-битное целое со знаком signed char
Uint8Array 1 8-битное без знаковое целое unsigned char
Int16Array 2 16-битное целое со знаком short
Uint16Array 2 16-битное без знаковое целое unsigned short
Int32Array 4 32-битное целое со знаком int
Uint32Array 4 32-битное без знаковое целое unsigned int
Float32Array 4 32-битное число с плавающей точкой float
Float64Array 8 64-битное число с плавающей точкой double



Создадим типизированный массив


Чтобы создать типизированный массив нужно воспользоваться конструктором название которого аналогично названию типа, для примера рассмотрим Uint8Array.
var ls1 = new Uint8Array(10),  //Создадим массив с четким указанием границ
    ls2 = new Uint8Array([1,2,3,4,5]); //Создадим массив из другого массива (может быть imageData или другой типизированный массив), при этом длина нового массива будет соответствовать длине инициальзирующего


Заполним массив


Заполнение по индексу работает также как и в любых других массивах, но кроме них в массив можно вставить другой массив с указанным смещением.
ls1.set(ls2,3); //Заметьте что если какой-то элемент массива не имеет значения то получая значение вы получите не undefined, а 0.


Получим под-массив


Кроме того мы можем получать часть массива.
var ls3 = ls1.subarray(2,5), //{0:0, 1:1, 2:2, 3:3, 4:4}  -- под-массив с элементами от 2-го до 5-го
    ls4 = ls1.subarray(6); //{0:4, 1:5, 2:0, 3:0} -- под-массив с элементами от 6-го до последнего


Производительность


Рассмотрим простой синтетический тест, созданный специально для быстрой работы с типизированными значениями.
Вариант с использованием типизированных массивов.
var ls1 = new Uint8Array(320000),
    ls2 = new Uint8Array(320000),
	ls3 = new Uint8Array(320000);
	
for(var i=0;i<319999;i++){
	ls1[i] = i;
	ls2[i] = 32-i;
} //4ms

for(var i=0;i<319999;i++){
	ls3[i] = ls1[i] * ls2[i];
}//15ms

ls1.set(ls3.subarray(30,60),30) //11ms


var ls1 = [],
    ls2 = [],
	ls3 = [];
	
for(var i=0;i<319999;i++){
	ls1[i] = i;
	ls2[i] = 32-i;
} //26ms

for(var i=0;i<319999;i++){
	ls3[i] = ls1[i] * ls2[i];
}  //19ms

ls1.splice(30,30,ls3.slice(30,60))  //7ms

Как видно типизированные массивы пока не очень быстры в плане функций именно массивов, но во всем остальном они превосходят по производительности обычные массивы

Update: передача неправильного типа


Как подсказали в комментарии В WebGL используются правила конвертации типов из ECMA-262 (пункт 3 — Type Conversion Rules в спеке WebGL).
a = new Uint8Array(3);
a[1] = 4;
a[1] = 'asdasdsad';
a == {0:0, 1:0, 2:0}
Tags:
Hubs:
+23
Comments 20
Comments Comments 20

Articles