1. A. Buffer ist nur eine Ansicht zum Betrachten eines ArrayBuffer.
A Bufferist in der Tat ein FastBuffer, das extends(erbt von) Uint8Array, was eine Oktetteinheit ist Ansicht ( „partial Accessor“) des Ist - Speicher, eineArrayBuffer .
📜/lib/buffer.js#L65-L73 Node.js 9.4.0
class FastBuffer extends Uint8Array {
constructor(arg1, arg2, arg3) {
super(arg1, arg2, arg3);
}
}
FastBuffer.prototype.constructor = Buffer;
internalBuffer.FastBuffer = FastBuffer;
Buffer.prototype = FastBuffer.prototype;
2. Die Größe eines ArrayBufferund die Größe seiner Ansicht können variieren.
Grund Nr. 1: Buffer.from(arrayBuffer[, byteOffset[, length]]) .
Mit Buffer.from(arrayBuffer[, byteOffset[, length]])können Sie ein Buffermit Angabe des Basiswerts erstellenArrayBuffer sowie der Position und Größe der Ansicht .
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.
Grund Nr. 2: FastBuffer Speicherzuordnung.
Der Speicher wird je nach Größe auf zwei verschiedene Arten zugewiesen.
- Wenn die Größe weniger als die Hälfte der Größe eines Speicherpools beträgt und nicht 0 („klein“) ist, wird a verwendet Speicherpool verwendet , um den erforderlichen Speicher vorzubereiten.
- Sonst : es schafft eine dedizierte
ArrayBuffer Speicher , der genau zum erforderlichen Speicher passt.
📜 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));
}
Was meinst du mit einem „ Speicherpool "?
Ein Speicherpool ist ein vorab zugewiesener Speicherblock mit fester Größe , um kleine Speicherblöcke für Buffers aufzubewahren . Durch die Verwendung werden die kleinen Speicherblöcke eng zusammengehalten, wodurch dies verhindert wird Fragmentierung die durch die separate Verwaltung (Zuweisung und Freigabe) kleiner Speicherblöcke verursacht wird.
In diesem Fall handelt es sich bei den Speicherpools um ArrayBuffers, deren Größe standardmäßig 8 KB beträgt Buffer.poolSize. Dies ist in angegeben . Wenn ein kleiner Speicherblock für a Bufferbereitgestellt werden soll, wird geprüft, ob der letzte Speicherpool über genügend verfügbaren Speicher verfügt, um dies zu handhaben. In diesem Fall wird ein Element erstellt Buffer, das den angegebenen Teil des Speicherpools "anzeigt". Andernfalls wird ein neuer Speicherpool erstellt und so weiter.
Sie können auf den Basiswert ArrayBuffervon a zugreifen Buffer. Die Buffer‚s - bufferEigenschaft (das heißt, geerbt von Uint8Array) hält. Eine „kleine“ Buffer ‚s - bufferEigenschaft ist eine ArrayBuffer, die den gesamten Speicher - Pool darstellt. In diesem Fall variiert das ArrayBufferund das Bufferin der Größe.
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. Wir müssen also den Speicher extrahieren, den es " ansieht ".
An ArrayBufferhat eine feste Größe, daher müssen wir es herausziehen, indem wir eine Kopie des Teils erstellen. Dazu verwenden wir Buffer‚s byteOffsetEigentum und lengthImmobilien , die von vererbt werden Uint8Array, und das ArrayBuffer.prototype.sliceVerfahren , das eine Kopie eines Teils eines macht ArrayBuffer. Die hier beschriebene slice()-ing-Methode wurde von @ZachB inspiriert .
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. Leistungsverbesserung
Wenn Sie die Ergebnisse schreibgeschützt verwenden oder den BufferInhalt der Eingabe ändern möchten , können Sie unnötiges Kopieren des Speichers vermeiden.
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