JavaScript の配列は強力です:
作成時に長さを指定することはできませんが、動的に長さを変更します。通常の配列として読み取ることも、スタックとして使用することもできます。配列内の各要素の値や型を変更することもできます。
実際にはオブジェクトです。たとえば、次のような配列を作成できます。
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、subarray の 4 つのメソッドを提供します。
|
メソッドゲッター
type get(unsigned long Index)
指定されたインデックスにある要素を返します。
setter void set(unsigned long インデックス、
type 値)
指定されたインデックスにある要素を指定された値に設定します。
void
set(
TypedArray 配列、オプションの unsigned long オフセット) void
set(
type[] 配列、オプションの unsigned long オフセット)
配列に従って値を設定し、offsetはオフセット位置です。
TypedArray subarray(長い開始点、オプションの長い終了点)
開始ビットを begin、終了ビットを end として、新しい TypedArray を返します。
たとえば、要素を読み取るには、 を使用できます:
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); //5
使用できる設定要素 :
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); //5array[4] = 12;alert(array[ 4]);
を使用してコピーを取得します:
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 |
サイズ
説明
Web IDL タイプ
Cタイプ
Int8Array |
1 |
8 ビット符号付き整数 |
バイト |
署名付き文字 |
Uint8Array |
1 |
8 ビット符号なし整数 |
オクテット |
符号なし文字 |
Uint8ClampedArray |
1 |
8 ビット符号なし整数 (クランプ) |
オクテット |
符号なし文字 |
Int16Array |
2 |
16 ビット符号付き整数 |
短い |
短い |
Uint16Array |
2 |
16 ビット符号なし整数 |
符号なしショート |
符号なしショート |
Int32Array |
4 |
32 ビット符号付き整数 |
長い |
int |
Uint32Array |
4 |
32 ビット符号なし整数 |
符号なしロング |
符号なし整数 |
Float32Array |
4 |
32 ビット IEEE 浮動小数点数 |
無制限の浮動小数点数 |
float |
Float64Array |
8 |
64 ビット IEEE 浮動小数点数 |
無制限の double |
double |
テーブル> キャンバスで遊んだことがある方には、馴染みがあるかもしれません。
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); } function timer( __fun, __time, __callback){ var now = 0; function begin(){ var timeout = setTimeout(function(){ if(now !== __time){ 今 ; __fun(); begin(); }else{ if(timeArray1.length && timeArray2.length){ console.log("timeArray1 == " timeArray1 " 、平均 == " 平均(timeArray1)); console.log("timeArray2 == " timeArray2 ", 平均 == " 平均(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 よりも明らかに速いことがわかります (バーが長いほど時間がかかります)。
テスト 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(); (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 - time3); } //……
はすぐに Uint8ClampedArray を取得しますが、その取得速度も Array に比べて速いです。
テスト 3:顺序書入
//…… function check1(){ var array = new Uint8ClampedArray(5000000); var time1 = (new Date()).getTime(); for(var i = array.length;){ 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); } //……
U8C が U8C に作られ、比配列が U8C に作られることが多くなりました。
|