1. A. Buffer
ist nur eine Ansicht zum Betrachten eines ArrayBuffer
.
A Buffer
ist 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 ArrayBuffer
und 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 Buffer
mit 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 Buffer
s 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 ArrayBuffer
s, deren Größe standardmäßig 8 KB beträgt Buffer.poolSize
. Dies ist in angegeben . Wenn ein kleiner Speicherblock für a Buffer
bereitgestellt 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 ArrayBuffer
von a zugreifen Buffer
. Die Buffer
‚s - buffer
Eigenschaft (das heißt, geerbt von Uint8Array
) hält. Eine „kleine“ Buffer
‚s - buffer
Eigenschaft ist eine ArrayBuffer
, die den gesamten Speicher - Pool darstellt. In diesem Fall variiert das ArrayBuffer
und das Buffer
in 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 ArrayBuffer
hat eine feste Größe, daher müssen wir es herausziehen, indem wir eine Kopie des Teils erstellen. Dazu verwenden wir Buffer
‚s byteOffset
Eigentum und length
Immobilien , die von vererbt werden Uint8Array
, und das ArrayBuffer.prototype.slice
Verfahren , 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 Buffer
Inhalt 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