1. A Buffer
hanyalah tampilan untuk melihat ke dalam ArrayBuffer
.
A Buffer
, pada kenyataannya, adalah a FastBuffer
, yang extends
(mewarisi dari) Uint8Array
, yang merupakan tampilan satuan oktet ("pengakses parsial") dari memori aktual, an ArrayBuffer
.
📜 Node.js 9.4.0/lib/buffer.js#L65-L73
class FastBuffer extends Uint8Array {
constructor(arg1, arg2, arg3) {
super(arg1, arg2, arg3);
}
}
FastBuffer.prototype.constructor = Buffer;
internalBuffer.FastBuffer = FastBuffer;
Buffer.prototype = FastBuffer.prototype;
2. Ukuran ArrayBuffer
dan ukuran tampilan dapat bervariasi.
Alasan # 1: Buffer.from(arrayBuffer[, byteOffset[, length]])
.
Dengan Buffer.from(arrayBuffer[, byteOffset[, length]])
, Anda dapat membuat Buffer
dengan menentukan dasarnya ArrayBuffer
dan posisi serta ukuran tampilan.
const test_buffer = Buffer.from(new ArrayBuffer(50), 40, 10);
console.info(test_buffer.buffer.byteLength); // 50; the size of the memory.
console.info(test_buffer.length); // 10; the size of the view.
Alasan # 2: FastBuffer
alokasi memori.
Ini mengalokasikan memori dalam dua cara berbeda tergantung pada ukurannya.
- Jika ukurannya kurang dari setengah ukuran kolam memori dan bukan 0 ("kecil") : itu menggunakan kolam memori untuk menyiapkan memori yang diperlukan.
- Lain : itu menciptakan dedicated
ArrayBuffer
yang persis sesuai dengan memori yang diperlukan.
📜 Node.js 9.4.0/lib/buffer.js#L306-L320
function allocate(size) {
if (size <= 0) {
return new FastBuffer();
}
if (size < (Buffer.poolSize >>> 1)) {
if (size > (poolSize - poolOffset))
createPool();
var b = new FastBuffer(allocPool, poolOffset, size);
poolOffset += size;
alignPool();
return b;
} else {
return createUnsafeBuffer(size);
}
}
📜 Node.js 9.4.0/lib/buffer.js#L98-L100
function createUnsafeBuffer(size) {
return new FastBuffer(createUnsafeArrayBuffer(size));
}
Apa yang Anda maksud dengan " kumpulan memori ?"
Kumpulan memori adalah blok memori pra-alokasi ukuran tetap untuk menjaga potongan memori berukuran kecil untuk Buffer
s. Menggunakannya membuat potongan memori ukuran kecil tetap rapat, sehingga mencegah fragmentasi yang disebabkan oleh manajemen yang terpisah (alokasi dan deallokasi) dari potongan memori ukuran kecil.
Dalam kasus ini, kumpulan memori adalah ArrayBuffer
s yang ukurannya 8 KiB secara default, yang ditentukan dalam Buffer.poolSize
. Ketika akan menyediakan potongan memori ukuran kecil untuk a Buffer
, itu memeriksa apakah kumpulan memori terakhir memiliki cukup memori yang tersedia untuk menangani ini; jika demikian, itu menciptakan Buffer
yang “dilihat” potongan parsial diberikan dari kolam memori, jika tidak, itu menciptakan kolam memori baru dan sebagainya.
Anda dapat mengakses dasar ArrayBuffer
dari a Buffer
. The Buffer
's buffer
properti (yaitu, diwarisi dari Uint8Array
) memegang itu. Sebuah “kecil” Buffer
's buffer
properti merupakan ArrayBuffer
yang mewakili seluruh kolam memori. Jadi dalam hal ini, ArrayBuffer
dan Buffer
ukurannya bervariasi.
const zero_sized_buffer = Buffer.allocUnsafe(0);
const small_buffer = Buffer.from([0xC0, 0xFF, 0xEE]);
const big_buffer = Buffer.allocUnsafe(Buffer.poolSize >>> 1);
// A `Buffer`'s `length` property holds the size, in octets, of the view.
// An `ArrayBuffer`'s `byteLength` property holds the size, in octets, of its data.
console.info(zero_sized_buffer.length); /// 0; the view's size.
console.info(zero_sized_buffer.buffer.byteLength); /// 0; the memory..'s size.
console.info(Buffer.poolSize); /// 8192; a memory pool's size.
console.info(small_buffer.length); /// 3; the view's size.
console.info(small_buffer.buffer.byteLength); /// 8192; the memory pool's size.
console.info(Buffer.poolSize); /// 8192; a memory pool's size.
console.info(big_buffer.length); /// 4096; the view's size.
console.info(big_buffer.buffer.byteLength); /// 4096; the memory's size.
console.info(Buffer.poolSize); /// 8192; a memory pool's size.
3. Jadi kita perlu mengekstrak memori itu " dilihat ."
Sebuah ArrayBuffer
adalah tetap dalam ukuran, sehingga kita perlu untuk mengambil keluar dengan membuat salinan bagian. Untuk melakukan hal ini, kita menggunakan Buffer
's byteOffset
properti dan length
properti , yang diwarisi dari Uint8Array
, dan yang ArrayBuffer.prototype.slice
metode , yang membuat salinan bagian dari ArrayBuffer
. The slice()
Metode -ing disini terinspirasi oleh @ZachB .
const test_buffer = Buffer.from(new ArrayBuffer(10));
const zero_sized_buffer = Buffer.allocUnsafe(0);
const small_buffer = Buffer.from([0xC0, 0xFF, 0xEE]);
const big_buffer = Buffer.allocUnsafe(Buffer.poolSize >>> 1);
function extract_arraybuffer(buf)
{
// You may use the `byteLength` property instead of the `length` one.
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);
}
// A copy -
const test_arraybuffer = extract_arraybuffer(test_buffer); // of the memory.
const zero_sized_arraybuffer = extract_arraybuffer(zero_sized_buffer); // of the... void.
const small_arraybuffer = extract_arraybuffer(small_buffer); // of the part of the memory.
const big_arraybuffer = extract_arraybuffer(big_buffer); // of the memory.
console.info(test_arraybuffer.byteLength); // 10
console.info(zero_sized_arraybuffer.byteLength); // 0
console.info(small_arraybuffer.byteLength); // 3
console.info(big_arraybuffer.byteLength); // 4096
4. Peningkatan kinerja
Jika Anda menggunakan hasil sebagai hanya-baca, atau apa-apa untuk mengubah masukan Buffer
s'isi , Anda dapat menghindari yang tidak perlu menyalin memori.
const test_buffer = Buffer.from(new ArrayBuffer(10));
const zero_sized_buffer = Buffer.allocUnsafe(0);
const small_buffer = Buffer.from([0xC0, 0xFF, 0xEE]);
const big_buffer = Buffer.allocUnsafe(Buffer.poolSize >>> 1);
function obtain_arraybuffer(buf)
{
if(buf.length === buf.buffer.byteLength)
{
return buf.buffer;
} // else:
// You may use the `byteLength` property instead of the `length` one.
return buf.subarray(0, buf.length);
}
// Its underlying `ArrayBuffer`.
const test_arraybuffer = obtain_arraybuffer(test_buffer);
// Just a zero-sized `ArrayBuffer`.
const zero_sized_arraybuffer = obtain_arraybuffer(zero_sized_buffer);
// A copy of the part of the memory.
const small_arraybuffer = obtain_arraybuffer(small_buffer);
// Its underlying `ArrayBuffer`.
const big_arraybuffer = obtain_arraybuffer(big_buffer);
console.info(test_arraybuffer.byteLength); // 10
console.info(zero_sized_arraybuffer.byteLength); // 0
console.info(small_arraybuffer.byteLength); // 3
console.info(big_arraybuffer.byteLength); // 4096