1. A 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
s, розмір яких за замовчуванням дорівнює 8 KiB, що вказано в 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
«s 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