>  기사  >  웹 프론트엔드  >  HTML5_html5 튜토리얼 기술에 도입된 새로운 배열 TypedArray 소개

HTML5_html5 튜토리얼 기술에 도입된 새로운 배열 TypedArray 소개

WBOY
WBOY원래의
2016-05-16 15:50:331260검색

Javascript의 배열은 강력한 기능을 제공합니다:

생성 시 길이를 지정할 수 없지만 동적으로 길이를 변경합니다. 일반 배열로 읽거나 스택으로 사용할 수 있습니다. 배열에 있는 각 요소의 값은 물론 유형까지 변경할 수 있습니다.

실제로는 객체입니다. 예를 들어 다음과 같은 배열을 만들 수 있습니다.

코드 복사
Code 다음과 같습니다:

var array = new Array(10);

Javascript 배열의 강력함과 전능함은 우리에게 편리함을 가져다줍니다. 그러나 일반적으로:

만능인은 다양한 환경에서 사용될 수 있지만 모든 환경에 적합하지는 않습니다.

TypedArray는 Javascript에서 배열이 수행하는 "너무 많은 작업" 문제를 정확하게 해결하기 위해 등장했습니다.

원산지

TypedArray는 버퍼에서 바이너리 데이터를 읽을 수 있는 일반적인 고정 길이 버퍼 유형입니다.

Javascript가 바이너리 데이터를 처리하는 문제를 해결하기 위해 WEBGL 사양에 도입되었습니다.

TypedArray는 대부분의 최신 브라우저에서 지원됩니다. 예를 들어 다음 방법을 사용하여 TypedArray를 생성할 수 있습니다.

코드 복사
코드는 다음과 같습니다.

// 8바이트 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(unsigned long length)
새 TypedArray를 생성합니다. 길이는 고정 길이입니다.


코드 복사
코드는 다음과 같습니다.

TypedArray(TypedArray array)
TypedArray(type[] array)
새 TypedArray를 생성합니다. 각 요소는 배열에 따라 초기화되고 그에 따라 요소의 유형이 변환됩니다.


코드 복사
코드는 다음과 같습니다.

TypedArray(ArrayBuffer 버퍼, 선택적 unsigned long byteOffset, 선택적 unsigned long length)
버퍼에 대한 참조로 새 TypedArray를 생성합니다. byteOffset은 시작 오프셋이고 length는 길이입니다.

따라서 일반적으로 다음과 같은 방법으로 TypedArray를 만듭니다.

코드 복사
코드는 다음과 같습니다:

var array = new Uint8Array(10);

또는:

코드 복사
코드는 다음과 같습니다.

var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]);

데이터 운영

TypedArray는 데이터 작업을 위한 setter, getter, set 및 하위 배열의 네 가지 메서드를 제공합니다.

메소드 getter type get(부호 없는 긴 인덱스)

지정된 인덱스에 있는 요소를 반환합니다.

setter void set(부호 없는 긴 인덱스, 유형 값)

지정된 인덱스의 요소를 지정된 값으로 설정합니다.

void set(TypedArray 배열, 선택적 부호 없는 긴 오프셋) void set(type[] 배열, 선택적 부호 없는 긴 오프셋)

배열에 따라 값을 설정하며, offset은 오프셋 위치입니다.

TypedArray 하위 배열(긴 시작, 선택적인 긴 끝)

시작 비트가 시작이고 끝 비트가 종료인 새 TypedArray를 반환합니다.

예를 들어 요소를 읽으려면 :

을 사용할 수 있습니다. var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 경고(배열[4]);

설정 요소를 사용할 수 있습니다 :

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);

유형

类型 大小 描述 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
사이즈 설명 웹 IDL 유형 C타입 Int8Array 1 8비트 부호 있는 정수 바이트 부호 있는 문자 Uint8Array 1 8비트 부호 없는 정수 옥텟 부호 없는 문자 Uint8ClampedArray 1 8비트 부호 없는 정수(클램핑됨) 옥텟 부호 없는 문자 Int16Array 2 16비트 부호 있는 정수 짧게 짧게 Uint16Array 2 16비트 부호 없는 정수 부호 없는 짧은 부호 없는 짧은 Int32Array 4 32비트 부호 있는 정수 정수 Uint32Array 4 32비트 부호 없는 정수 부호 없는 긴 부호 없는 정수 Float32Array 4 32비트 IEEE 부동 소수점 수 무제한 부동 소수점 부동 Float64Array 8 64비트 IEEE 부동 소수점 수 무제한 이중 더블
캔버스를 가지고 놀아보신 분들이라면 익숙하실 겁니다.

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의 경우 base64를 사용하여 전송하는 것도 비용이 많이 드는 방법이며, 바이너리 전송으로 전환하는 것이 더 나은 방법일 수 있습니다.

물론 TypedArray에는 더 나은 성능과 같은 더 많은 이점이 있습니다. 아래에서는 이를 확인하기 위해 몇 가지 작은 테스트를 수행합니다.

테스트에 참여한 브라우저는 :

FireFox 17.0.1 및 Chrome 23.0.1271.97m

테스트1: 순차 읽기 속도 읽기

코드 복사
코드는 다음과 같습니다.

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);
}
함수 타이머( __fun, __time, __callback){
var now = 0;
function start(){
var timeout = setTimeout(function(){
if(now !== __time){
이제
__fun();
start();
}else{
if(timeArray1.length && timeArray2.length){
console.log("timeArray1 == " timeArray1 " ,average == "average(timeArray1));
console.log("timeArray2 == "timeArray2",average == "average(timeArray2));
}
__callback && __callback();
}
}, 100);
}
start();
}
functionaverage(__array){
var total = 0;
for(var i = __array .length; i--;){
total = __array[i];
}
return (total / __array.length);
}
timer(check1, 10, 함수( ){
타이머(check2, 10);
});


Uint8ClampedArray의 읽기 속도가 Array보다 확실히 빠른 것을 볼 수 있습니다(바가 길수록 시간이 더 많이 걸립니다).

테스트2: 무작위 읽기

코드 복사
코드는 다음과 같습니다

//……
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 = 새 배열 (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 - 시간3);
}
//……

随即读取中Uint8ClampedArray를 사용하여 Array를 변경할 수 있습니다.

테스트3:顺序写入

复代码
代码如下:

//……
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. 무작위() * 100);
}
var time4 = (new Date()).getTime();
console.log(time4 - time3);
timeArray2.push(time4 - time3 );
}
//……


테스트4: 复제조작업(U8C에서 U8C로, 배열에서 U8C로)




复主代码
代码如下:

//……
기능 확인1 (){
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. 무작위() * 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);
}
//…
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.