1. A Bufferเป็นเพียงมุมมองสำหรับการค้นหาไฟล์ArrayBufferไฟล์.
A Bufferในความเป็นจริงคือ a FastBufferซึ่งextends(สืบทอดมาจาก) Uint8Arrayซึ่งเป็นมุมมองหน่วยออกเตต(“ ตัวเข้าถึงบางส่วน”) ของหน่วยความจำจริง a ArrayBuffer.
📜 โหนด 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]])1:
ด้วยBuffer.from(arrayBuffer[, byteOffset[, length]])คุณสามารถสร้างBufferด้วยการระบุพื้นฐานArrayBufferและตำแหน่งและขนาดของมุมมอง
const test_buffer = Buffer.from(new ArrayBuffer(50), 40, 10);
console.info(test_buffer.buffer.byteLength);
console.info(test_buffer.length);
เหตุผล # 2: FastBufferจัดสรรหน่วยความจำ
จัดสรรหน่วยความจำในสองวิธีที่แตกต่างกันขึ้นอยู่กับขนาด
- หากขนาดน้อยกว่าครึ่งหนึ่งของขนาดของพูลหน่วยความจำและไม่ใช่ 0 (“ เล็ก”) : จะใช้พูลหน่วยความจำเพื่อเตรียมหน่วยความจำที่ต้องการ
- อื่น ๆ : มันสร้างเฉพาะ
ArrayBufferที่เหมาะกับหน่วยความจำที่ต้องการ
📜 โหนด 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);
}
}
📜 โหนด js 9.4.0/lib/buffer.js#L98-L100
function createUnsafeBuffer(size) {
return new FastBuffer(createUnsafeArrayBuffer(size));
}
คุณหมายถึงอะไรโดย " หน่วยความจำ "
สระว่ายน้ำของหน่วยความจำเป็นขนาดคงที่ก่อนจัดสรรบล็อกหน่วยความจำสำหรับการเก็บรักษาชิ้นหน่วยความจำขนาดเล็กสำหรับBuffers การใช้มันช่วยให้หน่วยความจำขนาดเล็กเข้าด้วยกันอย่างแน่นหนาดังนั้นจึงป้องกันการแยกส่วนที่เกิดจากการจัดการแยกต่างหาก (การจัดสรรและการจัดสรร) ของหน่วยความจำขนาดเล็ก
ในกรณีนี้พูลหน่วยความจำคือArrayBuffers ที่มีขนาด 8 KiB ตามค่าเริ่มต้นซึ่งระบุไว้ในBuffer.poolSize. เมื่อต้องการให้หน่วยความจำขนาดเล็กสำหรับ a Bufferจะตรวจสอบว่าพูลหน่วยความจำสุดท้ายมีหน่วยความจำเพียงพอที่จะจัดการสิ่งนี้หรือไม่ ถ้าเป็นเช่นนั้นมันจะสร้างBufferที่“มุมมอง”ที่ได้รับก้อนบางส่วนของสระว่ายน้ำของหน่วยความจำมิฉะนั้นมันจะสร้างสระว่ายน้ำหน่วยความจำใหม่และอื่น ๆ
คุณสามารถเข้าถึงพื้นฐานArrayBufferของไฟล์Buffer. Buffer's bufferคุณสมบัติ (นั่นคือสืบทอดมาจากUint8Array) ถือมัน “เล็ก”ของสถานที่ให้บริการเป็นที่หมายถึงสระว่ายน้ำของหน่วยความจำทั้งหมด ดังนั้นในกรณีนี้และแตกต่างกันไปในขนาด BufferbufferArrayBufferArrayBufferBuffer
const zero_sized_buffer = Buffer.allocUnsafe(0);
const small_buffer = Buffer.from([0xC0, 0xFF, 0xEE]);
const big_buffer = Buffer.allocUnsafe(Buffer.poolSize >>> 1);
console.info(zero_sized_buffer.length);
console.info(zero_sized_buffer.buffer.byteLength);
console.info(Buffer.poolSize);
console.info(small_buffer.length);
console.info(small_buffer.buffer.byteLength);
console.info(Buffer.poolSize);
console.info(big_buffer.length);
console.info(big_buffer.buffer.byteLength);
console.info(Buffer.poolSize);
3. ดังนั้นเราต้องดึงหน่วยความจำออกมา " ดู "
ArrayBufferได้รับการแก้ไขในขนาดดังนั้นเราจึงจำเป็นที่จะดึงมันออกมาด้วยการทำสำเนาส่วนที่ การทำเช่นนี้เราจะใช้BufferของbyteOffsetสถานที่ให้บริการและlengthสถานที่ให้บริการที่ได้รับมาจากUint8Arrayและวิธีการซึ่งทำให้สำเนาส่วนหนึ่งของการเป็น วิธีไอเอ็นจีในเอกสารฉบับนี้ได้รับแรงบันดาลใจจาก@ZachBArrayBuffer.prototype.sliceArrayBufferslice()
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)
{
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);
}
const test_arraybuffer = extract_arraybuffer(test_buffer);
const zero_sized_arraybuffer = extract_arraybuffer(zero_sized_buffer);
const small_arraybuffer = extract_arraybuffer(small_buffer);
const big_arraybuffer = extract_arraybuffer(big_buffer);
console.info(test_arraybuffer.byteLength);
console.info(zero_sized_arraybuffer.byteLength);
console.info(small_arraybuffer.byteLength);
console.info(big_arraybuffer.byteLength);
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;
}
return buf.subarray(0, buf.length);
}
const test_arraybuffer = obtain_arraybuffer(test_buffer);
const zero_sized_arraybuffer = obtain_arraybuffer(zero_sized_buffer);
const small_arraybuffer = obtain_arraybuffer(small_buffer);
const big_arraybuffer = obtain_arraybuffer(big_buffer);
console.info(test_arraybuffer.byteLength);
console.info(zero_sized_arraybuffer.byteLength);
console.info(small_arraybuffer.byteLength);
console.info(big_arraybuffer.byteLength);