TypeScript'te TypedArray

TypeScript'te TypedArray

Bu makale TypeScript'teki TypedArray öğesini açıklar.

Pratik örnekler de dahil olmak üzere TypeScript'te TypedArray'i açıklayacağız.

YouTube Video

TypeScript'te TypedArray

TypedArray, ikili verileri verimli bir şekilde işlemek için kullanılan bir mekanizmadır. Özellikle büyük resim verileri, ağ bayt akışları ve WebGL için sayısal diziler gibi düşük seviyeli ikili işlemler için çok kullanışlıdır.

ArrayBuffer nasıl oluşturulur

ArrayBuffer, sabit uzunlukta bir bayt bölgesini temsil eder. Önce bir tampon oluşturun ve boyutunu ile bayt uzunluğunu kontrol edin.

1// Create an ArrayBuffer of 16 bytes
2const buffer: ArrayBuffer = new ArrayBuffer(16);
3console.log("buffer.byteLength:", buffer.byteLength); // 16
  • Bu kod, 16 bayttan oluşan boş bir bölge oluşturur. ArrayBuffer'ın kendisi okuma/yazma işlevlerine sahip değildir; bu nedenle, ona TypedArray veya DataView aracılığıyla erişirsiniz.

TypedArray tipleri

Aşağıdakiler gibi pek çok TypedArray türü vardır. Bunlar, işledikleri veri türüne ve boyutuna bağlı olarak farklılık gösterir.

TypedArray Veri Türü Bit Boyutu
Int8Array 8-bit tamsayı 8 bit
Uint8Array İşaretsiz 8-bit tamsayı 8 bit
Uint8ClampedArray Kısılmış işaretsiz 8-bit tamsayı 8 bit
Int16Array 16-bit tamsayı 16 bit
Uint16Array İşaretsiz 16-bit tamsayı 16 bit
Int32Array 32-bit tamsayı 32 bit
Uint32Array İşaretsiz 32-bit tamsayı 32 bit
Float32Array 32 bitlik kayan noktalı sayı 32 bit
Float64Array 64 bitlik kayan noktalı sayı 64 bit

Temel TypedArrayler (Uint8Array, Int16Array, Float32Array vb.)

TypedArray, bir ArrayBuffer üzerinde 'tipli bir görünüm' oluşturur. Aşağıda bazı tipik TypedArraylerin nasıl oluşturulup kullanılacağına dair örnekler bulunmaktadır.

 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);
  • Aynı ArrayBuffer üzerinde birden fazla görünüm oluşturarak, aynı belleği farklı türlerde veya ayrıntı seviyelerinde okuyup yazabilirsiniz. Görünümün length değeri eleman sayısını, byteLength ise bayt sayısını ifade eder.

Yazma ve okuma (bayt düzeyinde işlemler)

Bir TypedArray'e bir değer yazdığınızda, bellekteki ilgili baytlar güncellenir. Aynı tamponu farklı bir görünümle okuduğunuzda değişiklikleri görebilirsiniz.

 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
  • Bu örnekte, bir bayt dizisi yazıp ardından aynı alanı 32 bitlik bir tamsayı olarak okuyoruz. Çıktının çalıştırma ortamının endianness'ına bağlı olduğunu unutmayın.

Endianness (bayt sıralaması) ve DataView

Çevreye bağlı endianness sorunlarını kontrol etmek istiyorsanız DataView kullanışlıdır. DataView, okuma ve yazma sırasında endianness'ı belirtmenizi sağlar.

 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, baytları ayrıntılı şekilde okumak ve yazmak için kullanışlı bir mekanizmadır. İmzalı/işaretsiz tamsayılar ve kayan noktalı sayılar gibi çeşitli türleri destekler ve endianness (bayt sırası) açıkça belirtmenize olanak tanır; bu, ikili protokolleri uygularken çok faydalıdır.

subarray ile slice arasındaki fark

TypedArray'in subarray metodu, orijinal tamponu paylaşan bir görünüm döndürürken; slice ise yeni bir kopya döndürür. Kullanılan yönteme bağlı olarak performans ve yan etkiler değişir.

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
  • Paylaşılan görünümü değiştirirseniz, orijinal dizi de değişir, bu da istenmeyen yan etkilere neden olabilir. Orijinal diziyi güvenli bir şekilde korumak istiyorsanız, önceden slice() kullanarak bir kopya oluşturabilirsiniz.

Tamponları kopyalama ve tür dönüşümü (TypedArrayler arasında dönüşüm)

TypedArrayler arasında veri kopyalamanın ve set yöntemi ile bölümleri yapıştırmanın nasıl yapılacağını açıklayacağız.

 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]
  • Eleman tipleri farklıysa, sadece kopyalamak yerine, değerleri uygun şekilde (ör., yuvarlama veya aralık kontrolü) dönüştürmeniz gerekir. set fonksiyonu, aynı eleman tipine sahip TypedArrayler arasında hızlı kopyalama sağlar.

Pratik örnek: Basit bir ikili protokol ayrıştırıcısı

Burada, 1 baytlık tip, 2 baytlık veri uzunluğu ve ardından gelen yükten oluşan sabit formatlı ikili veriyi okuyan basit bir ayrıştırıcı örneği sunuyoruz.

 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));
  • Bu örnekte, başlık DataView ile okunur ve payload dilimi Uint8Array ile oluşturulur. Endianness ve tampon uzunluğu kontrolü önemlidir.

Web API ve TypedArray (Örnek: ikili veri çekme)

Bu, bir ağ isteğinden alınan ArrayBuffer'ın TypedArray kullanılarak nasıl işleneceğine dair tipik bir örnektir.

 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");
  • Response.arrayBuffer() ile alınan ArrayBuffer'ı doğrudan bir TypedArray'a aktarabilirsiniz. Resimler, ses veya özel ikili protokoller için kullanılır.

Performans ipuçları ve yaygın tuzaklar

TypedArray kullanırken bilmeniz faydalı olacak bazı 'performans ipuçları' ve 'yaygın hatalar' şunlardır:.

  • Gereksiz kopyalamalardan kaçının Büyük veriyi verimli şekilde işlemek için, subarray ile kısmi görünümler oluşturarak veya aynı ArrayBuffer'ı birden fazla görünüm arasında paylaşarak gereksiz kopyalamaları azaltabilirsiniz.

  • Endianness konusunda dikkatli olun Ağ iletişimi veya dosya formatlarında, veri sıralaması (bayt sırası) genellikle belirlenmiştir. DataView kullanarak, okuma ve yazmada endianness'ı açıkça belirtebilir, yanlış yorumlamaların önüne geçebilirsiniz.

  • Her tür için değer aralıklarının farkında olun Örneğin, Uint8 yalnızca 0 ile 255 arasındaki değerleri temsil edebilir. Negatif bir değer girerseniz, kesilme veya değer taşması meydana gelebilir, bu yüzden gerektiğinde dönüşüm kurallarını tanımlamalısınız.

  • Çöp toplayıcıya binen yükü göz önünde bulundurun Büyük ArrayBufferları sık sık yeniden oluşturmak, bellek yönetimi yükünü artırır. Performansın kritik olduğu durumlarda, mevcut tamponları mümkün olduğunca yeniden kullanacak şekilde kod tasarımı yapmayı düşünebilirsiniz.

Özet

TypedArray, ikili verileri hızlı ve verimli bir şekilde işlemek için kullanılan bir mekanizmadır. Sabit uzunlukta bayt alanı ayıran ArrayBuffer ile, içeriği belirli türlerle okuyan ve yazan TypedArray veya DataView'ı birleştirerek esnek ikili işlemler gerçekleştirebilirsiniz. Kullanım durumunuza bağlı olarak, subarray/slice veya DataView kullanmayı seçebilir ve uygulamanızı bit sırası (endianness) ve kopyalar konusunda dikkatli olarak tasarlayabilirsiniz.

Yukarıdaki makaleyi, YouTube kanalımızda Visual Studio Code'u kullanarak takip edebilirsiniz. Lütfen YouTube kanalını da kontrol edin.

YouTube Video