Array dalam Javascript adalah lelaki yang berkuasa:
Anda tidak boleh menentukan panjang semasa menciptanya, tetapi menukar panjang secara dinamik. Anda boleh membacanya sebagai tatasusunan biasa, atau menggunakannya sebagai timbunan. Anda boleh menukar nilai dan juga jenis setiap elemen dalam tatasusunan.
Nah, sebenarnya ia adalah objek Sebagai contoh, kita boleh mencipta tatasusunan seperti ini:
var array = new Array(10);
Kuasa dan kemahakuasaan tatasusunan Javascript membawa kemudahan kepada kami. Tetapi secara umum:
Perkara yang maha kuasa boleh digunakan dalam pelbagai persekitaran, tetapi ia mungkin tidak sesuai untuk semua persekitaran.
TypedArray muncul tepat untuk menyelesaikan masalah "terlalu banyak perkara yang dilakukan" oleh tatasusunan dalam Javascript.
Asal usul
TypedArray ialah jenis penimbal panjang tetap umum yang membenarkan membaca data binari dalam penimbal.
Ia telah diperkenalkan dalam spesifikasi WEBGL untuk menyelesaikan masalah pemprosesan data binari Javascript.
TypedArray telah disokong oleh kebanyakan penyemak imbas moden Contohnya, anda boleh mencipta TypedArray menggunakan kaedah berikut:
// Cipta ArrayBuffer 8-bait
var b = new ArrayBuffer(8);
// Cipta rujukan kepada b, jenis ialah Int32, bermula Kedudukan ialah 0, kedudukan akhir ialah penghujung penimbal
var v1 = new Int32Array(b);
// Buat rujukan kepada b, jenisnya ialah Uint8, kedudukan permulaan ialah 2, kedudukan akhir ialah penghujung penimbal
var v2 = new Uint8Array(b, 2);
// Buat rujukan kepada b, taip ialah Int16, kedudukan permulaan ialah 2, jumlah panjang ialah 2
var v3 = new Int16Array(b, 2 , 2);
maka susun atur rujukan yang ditimbal dan dibuat ialah:
变量 |
索引 |
|
字节数 |
b = |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
|
索引数 |
v1 = |
0 |
1 |
v2 = |
|
0 |
1 |
2 |
3 |
4 |
5 |
v3 = |
|
0 |
1 |
|
Ini bermakna elemen ke-0 bagi tatasusunan v1 jenis Int32 ialah 0-3 bait b jenis ArrayBuffer, dan seterusnya.
Pembina
Di atas kami mencipta TypedArray melalui ArrayBuffer, tetapi sebenarnya, TypedArray menyediakan 3 pembina untuk mencipta kejadiannya.
|
Pembina
TypedArray(panjang tidak bertanda)
Buat TypedArray baharu, panjang ialah panjang tetapnya.
TypedArray(TypedArray array)
TypedArray(type[] tatasusunan)
Mencipta TypedArray baharu, setiap elemen dimulakan mengikut tatasusunan, dan elemen ditukar jenis dengan sewajarnya.
TypedArray(Penimbal ArrayBuffer, byteOffset panjang yang tidak ditandatangani pilihan, panjang panjang yang tidak ditandatangani pilihan)
Buat TypedArray baharu sebagai rujukan kepada penimbal, byteOffset ialah ofset permulaannya dan panjang ialah panjangnya.
Jadi biasanya kami mencipta TypedArray dengan cara berikut:
var array = new Uint8Array(10);
atau:
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]);
Kendalian Data
TypedArray menyediakan empat kaedah: setter, getter, set dan subarray untuk operasi data.
|
Pengambil kaedah
taip dapatkan(indeks panjang tidak ditandatangani)
Mengembalikan elemen pada indeks yang ditentukan.
set void penetap(indeks panjang tidak ditandatangani, nilai
jenis)
Tetapkan elemen pada indeks yang ditentukan kepada nilai yang ditentukan.
void
set(
TypedArray tatasusunan, opsional unsigned long offset) void
set(
type[] array, optional unsigned long offset)
Tetapkan nilai mengikut tatasusunan, dan offset ialah kedudukan offset.
TypedArray subarray(mula panjang, hujung panjang pilihan)
Mengembalikan TypedArray baharu, dengan bit permulaan dimulakan dan bit pengakhiran diakhiri.
Sebagai contoh, untuk membaca elemen anda boleh menggunakan :
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
Elemen tetapan boleh digunakan :
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 4]); //12
Dapatkan salinan menggunakan :
var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
Jenis
类型 |
大小 |
描述 |
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 |
Saiz
Penerangan
Jenis IDL Web
Jenis C
Int8Array |
1 |
8-bit integer bertandatangan |
bait |
char yang ditandatangani |
Uint8Array |
1 |
8-bit unsigned integer |
oktet |
unsigned char |
Uint8ClampedArray |
1 |
8-bit unsigned integer (diapit) |
oktet |
unsigned char |
Int16Array |
2 |
integer bertanda 16 bit |
pendek |
pendek |
Uint16Array |
2 |
16-bit unsigned integer |
pendek yang tidak ditandatangani |
pendek yang tidak ditandatangani |
Int32Array |
4 |
integer bertanda 32-bit |
panjang |
int |
Uint32Array |
4 |
32-bit unsigned integer |
panjang tidak ditandatangani |
unsigned int |
Float32Array |
4 |
Nombor titik terapung IEEE 32-bit |
apungan tanpa had |
terapung |
Float64Array |
8 |
nombor titik terapung IEEE 64-bit |
double tanpa had |
double |
Mereka yang pernah bermain dengan kanvas mungkin menganggapnya biasa.
Kerana tatasusunan yang digunakan untuk menyimpan data imej dalam ImageData adalah jenis Uint8ClampedArray.
Contohnya:
var context = document.createElement("canvas").getContext("2d");var imageData = context.createImageData(100, 100);console.log(imageData.data);
yang muncul sebagai dalam FireBug:
Uint8ClampedArray { 0=0, 1=0, 2=0, lagi...}
Mengapa menggunakan TypedArray
Kami tahu bahawa nombor dalam Javascript ialah nombor titik terapung 64-bit. Untuk imej binari (setiap piksel imej disimpan sebagai integer tidak bertanda 8-bit), jika anda ingin menggunakan datanya dalam tatasusunan Javascript, ia bersamaan dengan menggunakan 8 kali memori imej untuk menyimpan data satu imej. Ini jelas sekali tidak saintifik. TypedArray boleh membantu kami menggunakan hanya 1/8 daripada memori asal untuk menyimpan data imej.
Atau untuk WebSocket, menggunakan base64 untuk penghantaran juga merupakan kaedah yang lebih mahal, dan beralih kepada penghantaran binari mungkin kaedah yang lebih baik.
Sudah tentu, TypedArray mempunyai lebih banyak faedah, seperti prestasi yang lebih baik Di bawah kami menjalankan beberapa ujian kecil untuk mengesahkan ini.
Pelayar yang mengambil bahagian dalam ujian ialah :
FireFox 17.0.1 dan Chrome 23.0.1271.97m
Ujian1: Bacaan kelajuan bacaan berurutan
var timeArray1 = []; var timeArray2 = []; function check1(){ var array = new Uint8ClampedArray(5000000); for(var i = array.length; i- -;){ tatasusunan[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){ sekarang ; __fun(); begin(); }lain{ if(timeArray1.length && timeArray2.length){ console.log("timeArray1 == " timeArray1 " , average == " average(timeArray1)); console.log("timeArray2 == " timeArray2 ", average == " average(timeArray2)); } __callback && __callback(); } }, 100); } begin(); } purata fungsi(__array){ var total = 0; for(var i = __array .length; i--;){ jumlah = __array[i]; } return (jumlah / __array.length); } pemasa(check1, 10, function( ){ pemasa(check2, 10); });
Dapat dilihat bahawa kelajuan bacaan Uint8ClampedArray jelas lebih cepat daripada Array (semakin panjang bar, lebih banyak masa yang diperlukan).
Ujian2: Bacaan rawak
//…… semakan fungsi1(){ tatasusunan var = Uint8ClampedArray(5000000); untuk(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 - masa3); } //……
随即读取中Uint8ClampedArray的读取速度也是比Array要快的。
Ujian3:顺序写入
semakan fungsi1(){ tatasusunan var = Uint8ClampedArray(5000000); var time1 = (Tarikh baharu()).getTime(); untuk(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. rawak() * 100); } var time4 = (new Date()).getTime(); console.log(time4 - time3); timeArray2.push(time4 - time3 ); } //……
Ujian4:复制操作(U8C ke U8C 和 Tatasusunan kepada U8C)
semak fungsi (){ tatasusunan var = Uint8ClampedArray(5000000); untuk(var i = array.length; i--;){ tatasusunan[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); } semakan fungsi2(){ tatasusunan var = Tatasusunan baharu(5000000); untuk(var i = tatasusunan.panjang; i--;){ tatasusunan[i] = Math.floor(Math. rawak() * 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快得多。
|