TypedArray dalam TypeScript

TypedArray dalam TypeScript

Artikel ini menerangkan TypedArray dalam TypeScript.

Kami akan menerangkan TypedArray dalam TypeScript, termasuk contoh-contoh praktikal.

YouTube Video

TypedArray dalam TypeScript

TypedArray ialah satu mekanisme untuk mengendalikan data binari secara cekap. Ia amat berguna untuk operasi binari aras rendah seperti data imej bersaiz besar, aliran bait rangkaian, dan tatasusunan angka untuk WebGL.

Cara mencipta ArrayBuffer

ArrayBuffer mewakili kawasan bait dengan panjang tetap. Mula-mula, cipta satu penimbal (buffer) dan periksa saiz serta panjang baitnya.

1// Create an ArrayBuffer of 16 bytes
2const buffer: ArrayBuffer = new ArrayBuffer(16);
3console.log("buffer.byteLength:", buffer.byteLength); // 16
  • Kod ini mencipta satu kawasan kosong sebanyak 16 bait. ArrayBuffer sendiri tidak mempunyai fungsi baca/tulis, jadi anda perlu mengaksesnya melalui TypedArray atau DataView.

Jenis-jenis TypedArray

Terdapat pelbagai jenis TypedArray, seperti berikut. Ini berbeza bergantung pada jenis data dan saiz yang mereka kendalikan.

TypedArray Jenis Data Saiz Bit
Int8Array Integer 8-bit 8 bit
Uint8Array Integer 8-bit tanpa tanda 8 bit
Uint8ClampedArray Integer 8-bit tanpa tanda terkawal 8 bit
Int16Array Integer 16-bit 16 bit
Uint16Array Integer 16-bit tanpa tanda 16 bit
Int32Array Integer 32-bit 32 bit
Uint32Array Integer 32-bit tanpa tanda 32 bit
Float32Array Nombor titik terapung 32-bit 32 bit
Float64Array Nombor titik terapung 64-bit 64 bit

TypedArray asas (Uint8Array, Int16Array, Float32Array, dll.)

TypedArray mencipta satu 'pandangan bertip' di atas ArrayBuffer. Di bawah adalah contoh ciptaan dan penggunaan beberapa TypedArray yang tipikal.

 1// Create a buffer and different typed views over it
 2const buf = new ArrayBuffer(8); // 8 bytes
 3
 4// Create views
 5const u8 = new Uint8Array(buf);    // 8 x uint8
 6const i16 = new Int16Array(buf);   // 4 x int16 (since each int16 is 2 bytes)
 7const f32 = new Float32Array(buf); // 2 x float32 (4 bytes each)
 8
 9console.log("Uint8 length:", u8.length);
10console.log("Int16 length:", i16.length);
11console.log("Float32 length:", f32.length);
  • Dengan mencipta pelbagai pandangan ke atas ArrayBuffer yang sama, anda boleh membaca dan menulis memori yang sama dengan jenis atau tahap butiran yang berbeza. length bagi pandangan ialah bilangan unsur, manakala byteLength ialah bilangan bait.

Menulis dan membaca (operasi aras bait)

Apabila anda menulis nilai ke dalam TypedArray, bait yang berkaitan dalam memori akan dikemas kini. Anda boleh melihat perubahan apabila membaca penimbal yang sama menggunakan pandangan yang berbeza.

 1// Demonstrate writing via one view and reading via another
 2const buffer2 = new ArrayBuffer(4);
 3const u8view = new Uint8Array(buffer2);
 4const u32view = new Uint32Array(buffer2);
 5
 6u8view[0] = 0x78;
 7u8view[1] = 0x56;
 8u8view[2] = 0x34;
 9u8view[3] = 0x12;
10
11console.log("Uint8 bytes:", Array.from(u8view)); // [120, 86, 52, 18]
12console.log("Uint32 value (platform endianness):", u32view[0]); // value depends on endianness
  • Dalam contoh ini, kita menulis urutan bait dan kemudian membaca kawasan yang sama sebagai integer 32-bit. Perlu diingat bahawa output bergantung pada endianness persekitaran pelaksanaan.

Endianness (susunan bait) dan DataView

DataView berguna jika anda ingin mengawal isu endianness yang bergantung kepada persekitaran. DataView membolehkan anda menetapkan endianness semasa membaca dan menulis.

 1// Use DataView to read/write with explicit endianness control
 2const b = new ArrayBuffer(4);
 3const dv = new DataView(b);
 4
 5// write little-endian 32-bit integer
 6dv.setUint32(0, 0x12345678, true);
 7
 8// read as little-endian and big-endian
 9const little = dv.getUint32(0, true);
10const big = dv.getUint32(0, false);
11
12console.log("little-endian read:", little.toString(16)); // "12345678"
13console.log("big-endian read:", big.toString(16));       // different value
  • DataView ialah mekanisme yang mudah untuk membaca dan menulis bait secara terperinci. Ia menyokong pelbagai jenis, seperti integer bertanda atau tanpa tanda dan nombor titik apungan, dan membolehkan anda menetapkan endianness (susunan bait) secara jelas, yang sangat berguna ketika melaksanakan protokol binari.

Perbezaan antara subarray dan slice

subarray dari TypedArray mengembalikan satu pandangan yang berkongsi penimbal asal, manakala slice menghasilkan salinan baharu. Prestasi dan kesan sampingan berbeza bergantung pada yang mana anda gunakan.

1const base = new Uint8Array([1, 2, 3, 4, 5]);
2
3const shared = base.subarray(1, 4); // shares underlying buffer
4const copied = base.slice(1, 4);    // copies data
5
6shared[0] = 99;
7console.log("base after shared modification:", base); // shows change
8console.log("copied remains:", copied);              // unaffected
  • Jika anda mengubah paparan yang dikongsi, tatasusunan asal juga akan berubah, yang mungkin menyebabkan kesan sampingan yang tidak diingini. Jika anda ingin mengekalkan tatasusunan asal dengan selamat, anda boleh membuat salinan terlebih dahulu menggunakan slice().

Menyalin penimbal dan penukaran jenis (penukaran antara TypedArray)

Kami akan menerangkan cara menyalin data antara TypedArray dan cara menampal bahagian menggunakan kaedah set.

 1// Copy and convert between typed arrays
 2const src = new Float32Array([1.5, 2.5, 3.5]);
 3const dst = new Uint16Array(src.length);
 4
 5// Convert by mapping (explicit conversion)
 6for (let i = 0; i < src.length; i++) {
 7  dst[i] = Math.round(src[i]); // simple conversion rule
 8}
 9console.log("converted dst:", Array.from(dst)); // [2, 2, 4]
10
11// Using set to copy bytes (requires compatible underlying buffer or same element type)
12const src2 = new Uint8Array([10, 20, 30]);
13const dst2 = new Uint8Array(6);
14dst2.set(src2, 2); // copy src2 into dst2 starting at index 2
15console.log("dst2 after set:", Array.from(dst2)); // [0,0,10,20,30,0]
  • Jika jenis unsur berbeza, anda perlu menukar nilai, seperti pembundaran atau semakan julat, dan tidak hanya menyalin begitu sahaja. set membolehkan penyalinan pantas antara TypedArray dengan jenis unsur yang sama.

Contoh praktikal: Penghurai protokol binari (pelaksanaan ringkas)

Di sini, kami memperkenalkan satu contoh penghurai ringkas yang membaca data binari berformat tetap yang terdiri daripada 1 bait jenis, 2 bait panjang data, dan muatan seterusnya.

 1// Simple binary message parser:
 2// format: [type: uint8][length: uint16 BE][payload: length bytes]
 3function parseMessages(buffer: ArrayBuffer) {
 4  const dv = new DataView(buffer);
 5  let offset = 0;
 6  const messages: { type: number; payload: Uint8Array }[] = [];
 7
 8  while (offset + 3 <= dv.byteLength) {
 9    const type = dv.getUint8(offset);
10    const length = dv.getUint16(offset + 1, false); // big-endian
11    offset += 3;
12    if (offset + length > dv.byteLength) break; // truncated
13    const payload = new Uint8Array(buffer, offset, length);
14    messages.push({ type, payload });
15    offset += length;
16  }
17
18  return messages;
19}
20
21// Example usage
22const buf = new ArrayBuffer(1 + 2 + 3 + 1 + 2 + 2); // two messages
23const dv = new DataView(buf);
24let off = 0;
25// first message: type=1, length=3, payload=[1,2,3]
26dv.setUint8(off, 1); dv.setUint16(off + 1, 3, false); off += 3;
27new Uint8Array(buf, off, 3).set([1, 2, 3]); off += 3;
28// second message: type=2, length=2, payload=[9,8]
29dv.setUint8(off, 2); dv.setUint16(off + 1, 2, false); off += 3;
30new Uint8Array(buf, off, 2).set([9, 8]);
31
32console.log(parseMessages(buf));
  • Dalam contoh ini, tajuk dibaca menggunakan DataView, dan potongan payload dibuat dengan Uint8Array. Pemeriksaan endianness dan panjang penimbal adalah penting.

Web API dan TypedArray (Contoh: mengambil data binari)

Ini adalah contoh tipikal untuk mengendalikan ArrayBuffer yang diperoleh daripada permintaan rangkaian menggunakan TypedArray.

 1// Example of fetching binary and mapping to typed array
 2async function fetchBinary(url: string) {
 3  const res = await fetch(url);
 4  const ab = await res.arrayBuffer();
 5  const view = new Uint8Array(ab);
 6  // process view...
 7  console.log("received bytes:", view.length);
 8  return view;
 9}
10
11// Usage (call in async context)
12// fetchBinary("/path/to/file.bin");
  • Anda boleh terus hantarkan ArrayBuffer yang diperoleh menggunakan Response.arrayBuffer() kepada TypedArray. Ia digunakan untuk imej, audio, atau protokol binari tersuai.

Petua prestasi dan perangkap lazim

Berikut adalah beberapa 'petua prestasi' dan 'perangkap lazim' yang berguna diketahui apabila menggunakan TypedArray:.

  • Elakkan penyalinan yang tidak perlu Untuk memproses data besar dengan cekap, anda boleh mengurangkan penyalinan yang tidak perlu dengan mencipta pandangan separa menggunakan subarray atau berkongsi ArrayBuffer yang sama ke beberapa pandangan.

  • Berhati-hati dengan endianness Untuk komunikasi rangkaian atau format fail, susunan data (susunan bait) biasanya ditentukan. Menggunakan DataView membolehkan anda menetapkan endianness secara jelas semasa membaca dan menulis, mengelakkan tafsiran salah yang tidak diingini.

  • Ambil maklum julat nilai setiap jenis Sebagai contoh, Uint8 hanya boleh mewakili nilai dari 0 hingga 255. Jika anda memasukkan nilai negatif, pemotongan atau limpahan nilai mungkin berlaku, jadi anda harus menetapkan peraturan penukaran jika perlu.

  • Pertimbangkan beban pada pengumpulan sampah (garbage collection) Kerap mencipta semula ArrayBuffer yang besar meningkatkan beban pengurusan memori. Dalam situasi yang kritikal terhadap prestasi, anda boleh mempertimbangkan untuk mereka bentuk kod supaya menggunakan semula penimbal sedia ada sebanyak mungkin.

Ringkasan

TypedArray ialah mekanisme untuk mengendalikan data binari dengan pantas dan cekap. Dengan menggabungkan ArrayBuffer, yang menempah kawasan byte berpanjang tetap, bersama TypedArray atau DataView, yang membaca dan menulis kandungan menggunakan jenis tertentu, anda boleh melakukan operasi binari yang fleksibel. Bergantung kepada kes penggunaan anda, anda boleh memilih antara menggunakan subarray/slice atau DataView, dan mereka bentuk pelaksanaan anda dengan mengambil kira endianness dan salinan.

Anda boleh mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Sila lihat juga saluran YouTube kami.

YouTube Video