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, onaTypedArrayveyaDataViewaracı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ünlengthdeğeri eleman sayısını,byteLengthise 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.
setfonksiyonu, aynı eleman tipine sahipTypedArrayler 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
DataViewile okunur ve payload dilimiUint8Arrayile 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ınanArrayBuffer'ı doğrudan birTypedArray'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,
subarrayile 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.
DataViewkullanarak, 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,
Uint8yalnı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.