每日一贴,今天的内容关键字为类型数组
Javascript中的数组是个壮大的家伙:
- 你可以创立的时候不定规长度,而是动态的去变改长度。
- 你可以把他成当通普的数组去取读,也可以当他是堆栈来用使。
- 你可以变改数组中每一个元素的值甚至是类型。
好吧,其实他是一个对象,比如我们可以这样去创立数组:
var array = new Array(10);
万能的货色能在各种环境下用使,但却不一定适用于各种环境。
而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);
量变 | 索引 | |||||||
---|---|---|---|---|---|---|---|---|
字节数 | ||||||||
b = | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
索引数 | ||||||||
v1 = | 0 | 1 | ||||||
v2 = | 0 | 1 | 2 | 3 | 4 | 5 | ||
v3 = | 0 | 1 |
这表现Int32类型的v1数组的第0个元素是ArrayBuffer类型的b的第0-3个字节,如此等等。
构造函数
面上我们通过ArrayBuffer来创立TypedArray,而实际上,TypedArray供提了3个构造函数来创立他的例实。
构造函数 | |
---|---|
| |
| |
|
所以常通我们用面上的式方创立TypedArray:
var array = new Uint8Array(10);
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
数据作操
TypedArray供提了setter、getter、set和subarray四个法方停止数据作操。
法方 | |
---|---|
| |
| |
| |
|
例如取读元素可以用:
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]); //5 array[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);
数组类型
类型 | 巨细 | 描述 | Web IDL类型 | C 类型 |
---|---|---|---|---|
Int8Array | 1 | 8位有符号整数 | byte | signed char |
Uint8Array | 1 | 8位无符号整数 | octet | unsigned char |
Uint8ClampedArray | 1 | 8位无符号整数 (clamped) | octet | unsigned char |
Int16Array | 2 | 16位有符号整数 | short | short |
Uint16Array | 2 | 16位无符号整数 | unsigned short | unsigned short |
Int32Array | 4 | 32位有符号整数 | long | int |
Uint32Array | 4 | 32位无符号整数 | unsigned long | unsigned int |
Float32Array | 4 | 32位IEEE浮点数 | unrestricted float | float |
Float64Array | 8 | 64位IEEE浮点数 | unrestricted double | double |
玩过canvas的可能会觉得很眼生。
因为ImageData中用于存储图像数据的数组就是Uint8ClampedArray类型的。
例如:
var context = document.createElement("canvas").getContext("2d"); var imageData = context.createImageData(100, 100); console.log(imageData.data);
Uint8ClampedArray { 0=0, 1=0, 2=0, 更多...}
为什么要用TypedArray
我们晓得Javascript中数字是64位浮点数。则对于一个二进制片图(片图每一个像素点是以8位无符号整数存储的),如果要将其数据在Javascript数组中用使,相当于用使了片图8倍的内存来存储一个片图的数据,这显然是不科学的。而TypedArray能帮助我们只用使来原1/8的内存来存储片图数据。
或者对于WebSocket,如果用base64停止传输也是一个费花较高的式方,转而用使二进制送传是能可更好的式方。
当然,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 = setTimeout(function(){ if(now !== __time){ now++; __fun(); begin(); }else{ 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 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[Math.floor(Math.random() * 5000000)]; } 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[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.length; i--;){ array[i] = Math.floor(Math.random() * 100); } var temp; var array2 = new Uint8ClampedArray(5000000); var time1 = (new Date()).getTime(); array2.set(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.set(array); var time2 = (new Date()).getTime(); console.log(time2 - time1); timeArray2.push(time2 - time1); } //……
可见U8C复制到U8C,比Array复制到U8C快得多。
参考文献
文章结束给大家分享下程序员的一些笑话语录: 一条狗在街上闲逛,看见橱窗里一张告示:「招聘程序员。会编程,有团队精神,至少精通两种语言。均等机会。」
那条狗就进去申请,但是被拒绝了。
「我不能雇一条狗在公司里做事。」经理说。
狗不服气,指着告示上「均等机会」几字抗议。
经理没法,叹了口气,不屑地问道:「你会编程吗?」
那条狗默默地走到电脑前,编了个程序,运作准确。
「你有团队精神吗?」经理问。
那条狗掉头看了看门外,一大群野狗在外面虎视耽耽。
「我真的不能雇狗做这份工作。」经理气急败坏地说。
「就算会编程、有团队精神,但是我需要的雇员至少要能精通两种语言。」
那条狗抬头看着经理说:「喵-噢。」