С появлением WebGL появились и несколько новых типов данных, в частности типизированные массивы. Они все обладают похожим интерфейсом и по скорости значительно превосходят обычные массивы, обладают контролем границ и всего двумя методами и одним свойством. На данный момент если я не ошибаюсь то типизированные массивы поддерживаются последними версиями FireFox и Chrome.
Подробнее о типизированных массивах можно почитать в спецификации
Ну, а в статье мы рассмотрим основы основ
Чтобы создать типизированный массив нужно воспользоваться конструктором название которого аналогично названию типа, для примера рассмотрим Uint8Array.
Заполнение по индексу работает также как и в любых других массивах, но кроме них в массив можно вставить другой массив с указанным смещением.
Кроме того мы можем получать часть массива.
Рассмотрим простой синтетический тест, созданный специально для быстрой работы с типизированными значениями.
Вариант с использованием типизированных массивов.
Как видно типизированные массивы пока не очень быстры в плане функций именно массивов, но во всем остальном они превосходят по производительности обычные массивы
Как подсказали в комментарии В WebGL используются правила конвертации типов из ECMA-262 (пункт 3 — Type Conversion Rules в спеке WebGL).
Подробнее о типизированных массивах можно почитать в спецификации
Ну, а в статье мы рассмотрим основы основ
Типы типизированных массивов
Таблица украдена из спецификации
Тип | Размер в байтах | Описание | Аналог в 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}