javascript中的数组是个强大的家伙:
你可以创建的时候不规定长度,而是动态的去改变长度。你可以把他当成普通的数组去读取,也可以当他是堆栈来使用。你可以改变数组中每个元素的值甚至是类型。
好吧,其实他是一个对象,比如我们可以这样去创建数组:
复制代码 代码如下:
var array = new array(10);
javascript的数组的强大以及全能,给我们带来了便捷性。但一般而言:
全能的东西能在各种环境下使用,但却不一定适用于各种环境。
而typedarray正是为了解决javascript中数组“干太多事”而出现的。
起源
typedarray是一种通用的固定长度缓冲区类型,允许读取缓冲区中的二进制数据。
其在webgl规范中被引入用于解决javascript处理二进制数据的问题。
typedarray已经被大部分现代浏览器支持,例如可以用下面方法创建typedarray:
复制代码 代码如下:
// 创建一个8-byte的arraybuffer
var b = new arraybuffer(8);
// 创建一个b的引用,类型是int32,起始位置在0,结束位置为缓冲区尾部
var v1 = new int32array(b);
// 创建一个b的引用,类型是uint8,起始位置在2,结束位置为缓冲区尾部
var v2 = new uint8array(b, 2);
// 创建一个b的引用,类型是int16,起始位置在2,总长度为2
var v3 = new int16array(b, 2, 2);
则缓冲和创建的引用布局为:
这表示int32类型的v1数组的第0个元素是arraybuffer类型的b的第0-3个字节,如此等等。
构造函数
上面我们通过arraybuffer来创建typedarray,而实际上,typedarray提供了3个构造函数来创建他的实例。
构造函数
复制代码 代码如下:
typedarray(unsigned long length)
创建一个新的typedarray,length是其固定长度。
复制代码 代码如下:
typedarray(typedarray array)
typedarray(type[] array)
创建一个新的typedarray,其每个元素根据array进行初始化,元素进行了相应的类型转换。
复制代码 代码如下:
typedarray(arraybuffer buffer, optional unsigned long byteofft, optional unsigned long length)
创建一个新的typedarray,使其作为buffer的一个引用,byteofft为其起始的偏移量,length为其长度。
所以通常我们用下面的方式创建typedarray:
复制代码 代码如下:
var array = new uint8array(10);
或者:
复制代码 代码如下:
var array = new uint8array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
数据操作
typedarray提供了tter、getter、t和subarray四个方法进行数据操作。
方法getter
typeget(unsigned long index)
返回指定索引的元素。
tter void t(unsigned long index,
typevalue)
设置指定索引的元素为指定值。
void
t(
typedarrayarray, optional unsigned long offt)void
t(
type[] array, optional unsigned long offt)
根据array设置值,offt为偏移位置。
typedarray
subarray(long begin, optional long end)
返回一个新的typedarray,起始位为begin,结束位为end。
例如读取元素可以用:
var array = new uint8array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);alert(array[4]); //5
设置元素可以用:
var array = new uint8array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);alert(array[4]); //5array[4] = 12;alert(array[4]); //12
获取一个副本可以用:
var array = new uint8array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);var array2 = array.subarray(0);
数组类型
int8array
18位有符号整数byte
signed char
uint8array
18位无符号整数octet
unsigned char
uint8clampedarray
18位无符号整数 (clamped)octet
unsigned char
int16array
216位有符号整数short
short
uint16array
216位无符号整数unsigned short
unsigned short
int32array
432位有符号整数long
int
uint32array
432位无符号整数unsigned long
unsigned int
float32array
432位ieee浮点数unrestricted float
float
float64array
864位ieee浮点数unrestricted double
double
玩过canvas的可能会觉得很眼熟。
因为imagedata中用于存储图像数据的数组便是uint8clampedarray类型的。
例如:
var context = document.createelement(“canvas”).getcontext(“2d”);var imagedata = context.createimagedata(100, 100);console.log(imagedata.data);
其在firebug中显示为:
uint8clampedarray { 0=0, 1=0, 2=0, 更多…}
为什么要用typedarray
我们知道javascript中数字是64位浮点数。则对于一个二进制图片(图片每个像素点是以8位无符号整数存储的),如果要将其数据在javascript数组中使用,相当于使用了图片8倍的内存来存储一个图片的数据,这显然是不科学的。而typedarray能帮助我们只使用原来1/8的内存来存储图片数据。
或者对于websocket,如果用ba64进行传输也是一个花费较高的方式,转而使用二进制传送可能是更好的方式。
当然,typedarray还有更多好处,比如具有更好的性能,下面我们进行一些小测试来验证这一点。
参与测试的浏览器为:
firefox 17.0.1 和 chrome 23.0.1271.97m
test1:顺序读取速读
复制代码 代码如下:
var timearray1 = [];
var timearray2 = [];
function check1(){
var array = new uint8clampedarray(5000000);
for(var i = array.length; i–;){
array[i] = math.floor(math.random() * 100);
}
var temp;
var time1 = (new date()).gettime();
for(var i = array.length; i–;){
temp = array[i];
}
var time2 = (new date()).gettime();
console.log(time2 – time1);
timearray1.push(time2 – time1);
}
function check2(){
var array2 = new array(5000000);
for(var i = array2.length; i–;){
array2[i] = math.floor(math.random() * 100);
}
var temp;
var time3 = (new date()).gettime();
for(var i = array2.length; i–;){
temp = array2[i];
}
var time4 = (new date()).gettime();
console.log(time4 – time3);
timearray2.push(time4 – time3);
}
function timer(__fun, __time, __callback){
var now = 0;
function begin(){
var timeout = ttimeout(function(){
if(now !== __time){
now++;
__fun();
begin();
}el{
if(timearray1.length && timearray2.length){
console.log(“timearray1 == ” + timearray1 + “, average == ” + average(timearray1));
console.log(“timearray2 == ” + timearray2 + “, average == ” + average(timearray2));
}
__callback && __callback();
}
}, 100);
}
begin();
}
function average(__array){
var total = 0;
for(var i = __array.length; i–;){
total += __array[i];
}
return (total / __array.length);
}
timer(check1, 10, function(){
timer(check2, 10);
});
可见uint8clampedarray的读取速度明显比array要快(条状柱越长,代表花费时间越多)。
test2:随机读取
复制代码 代码如下:
//……
function check1(){
var ar屈服的反义词ray = new uint8clampedarray(5000000);
for(var i = array.length; i–;){
array[i] = math.floor(math.random() * 100);
}
var temp;
var time1 = (new date()).gettime();
for(var i = array.length; i–;){
temp = array[math.floor(math.random() * 5000000)];
}
var ti摆渡人豆瓣me2 = (new date()).gettime();
console.log(time2 – time1);
timearray1.push(time2 – time1);
}
function check2(){
var array2 = new array(5000000);
for(var i = array2.length; i–;){
array2[i] = math.floor(math.random() * 100);
}
var temp;
var time3 = (new date()).gettime();
for(var i = array2.length; i–;){
temp = array2[math.floor(math.random() * 5000000)];
}
var time4 = (new date()).gettime();
console.log(time4 – time3);
timearray2.push(time4 – time3);
}
//……
随即读取中uint8clampedarray的读取速度也是比array要快的。
test3:顺序写入
复制代码 代码如下:
//……
function check1(){
var array = new uint8clampedarray(5000000);
var time1 = (new date()).gettime();
for(var i = array.length; i–;){
array[i] = math.floor(math.random() * 100);
}
var time2 = (new date()).gettime();
console.log(time2 – time1);
timearray1.push(time2 – time1);
}
function check2(){
var array2 = new array(5000000);
var time3 = (new date()).gettime();
for(var i = array2.length; i–;){
array2[i] = math.floor(math.random() * 100);
}
var time4 = (new date()).gettime();
console.log(time4 – time3);
timearray2.push(time4 – time3);
}
//……
test4:复制操作(u8c to u8c和 array to u8c)
复制代码 代码如下:
//……
function check1(){
var array = new uint8clampedarray(5000000);
for(var i = array.l直接选举ength; i–;){
array[i] = math.floor(math.random(贵州警察学院官网) * 100);
}
var temp;
var array2 = new uint8c学校收费lampedarray(5000000);
var time1 = (new date()).gettime();
array2.t(array);
var time2 = (new date()).gettime();
console.log(time2 – time1);
timearray2.push(time2 – time1);
}
function check2(){
var array = new array(5000000);
for(var i = array.length; i–;){
array[i] = math.floor(math.random() * 100);
}
var temp;
var array2 = new uint8clampedarray(5000000);
var time1 = (new date()).gettime();
array2.t(array);
var time2 = (new date()).gettime();
console.log(time2 – time1);
timearray2.push(time2 – time1);
}
//……
可见u8c复制到u8c,比array复制到u8c快得多。
本文发布于:2023-04-03 06:54:07,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/3404c7a1aacdc73a056b1d30ab511eca.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:HTML5引入的新数组TypedArray介绍.doc
本文 PDF 下载地址:HTML5引入的新数组TypedArray介绍.pdf
留言与评论(共有 0 条评论) |