1. А Buffer
- это просто вид для изучения ArrayBuffer
.
Buffer
, По сути, представляет собой FastBuffer
, который extends
(наследует от) Uint8Array
, который представляет собой октет-блок вид ( «частичный аксессор») от фактической памяти, с 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. Размер ArrayBuffer
и размер его вида могут различаться.
Причина № 1: Buffer.from(arrayBuffer[, byteOffset[, length]])
.
С помощью Buffer.from(arrayBuffer[, byteOffset[, length]])
, вы можете создать Buffer
с указанием его основы ArrayBuffer
и позиции и размера представления.
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.
Причина № 2: FastBuffer
выделение памяти.
Он распределяет память двумя различными способами в зависимости от размера.
- Если размер меньше половины размера пула памяти и не равен 0 («маленький») : он использует пул памяти для подготовки необходимой памяти.
- Иначе : он создает выделенный,
ArrayBuffer
который точно соответствует требуемой памяти.
📜 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));
}
Что вы подразумеваете под « пул памяти ?»
Пул памяти является фиксированным размером предварительно выделен блоком памяти для хранения кусков памяти малого размера для Buffer
с. Его использование обеспечивает плотное соединение небольших блоков памяти, что предотвращает фрагментацию. вызванную раздельным управлением (выделением и освобождением) блоков памяти малого размера.
В этом случае используются пулы памяти ArrayBuffer
с размером по умолчанию 8 КиБ, который указан в Buffer.poolSize
. Когда он должен предоставить блок памяти небольшого размера для a Buffer
, он проверяет, имеет ли последний пул памяти достаточно доступной памяти для обработки этого; если это так, он создает объект, Buffer
который «просматривает» данный частичный фрагмент пула памяти, в противном случае он создает новый пул памяти и так далее.
Вы можете получить доступ к основному ArrayBuffer
из Buffer
. В Buffer
«S buffer
свойство (то есть, унаследованное от Uint8Array
) удерживает его. «Небольшой» «s свойство является , который представляет весь пул памяти. Так что в этом случае размер и меняется. Buffer
buffer
ArrayBuffer
ArrayBuffer
Buffer
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. Поэтому нам нужно извлечь память, которую он « просматривает ».
ArrayBuffer
Фиксируется в размерах, так что мы должны извлечь его, сделав копию части. Для этого мы используем Buffer
«ю.ш.byteOffset
имущество и length
имущество , которые наследуются от Uint8Array
и на ArrayBuffer.prototype.slice
метод , который делает копию части ArrayBuffer
. Метод slice()
-ing здесь был вдохновлен @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. Улучшение производительности
Если вы хотите использовать результаты только для чтения или если вы можете изменить Buffer
содержимое входных данных , вы можете избежать ненужного копирования в память.
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