1. การวิเคราะห์เปิด
บัฟเฟอร์บัฟเฟอร์ที่เรียกว่า "พื้นที่จัดเก็บชั่วคราว" ซึ่งเป็นชิ้นส่วนของหน่วยความจำที่เก็บข้อมูลอินพุตและเอาต์พุตชั่วคราว
ภาษา JS นั้นมีชนิดข้อมูลสตริงเท่านั้นและไม่มีชนิดข้อมูลไบนารี ดังนั้น NODEJS จึงจัดทำบัฟเฟอร์คอนสตรัคเตอร์ทั่วโลกที่เป็นเพื่อนในการสตริงเพื่อให้การดำเนินการกับข้อมูลไบนารี นอกเหนือจากการอ่านไฟล์เพื่อรับอินสแตนซ์บัฟเฟอร์แล้วยังสามารถสร้างได้โดยตรงเช่น:
การคัดลอกรหัสมีดังนี้:
var buffer = บัฟเฟอร์ใหม่ ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
บัฟเฟอร์คล้ายกับสตริง นอกเหนือจากการใช้แอตทริบิวต์. ความยาวเพื่อให้ได้ความยาวไบต์คุณยังสามารถใช้วิธี [ดัชนี] เพื่ออ่านไบต์ที่ตำแหน่งที่ระบุเช่น:
การคัดลอกรหัสมีดังนี้:
บัฟเฟอร์ [0]; // 0x68;
บัฟเฟอร์และสตริงสามารถแปลงเป็นกันได้เช่นข้อมูลไบนารีสามารถแปลงเป็นสตริงได้โดยใช้การเข้ารหัสที่ระบุ:
การคัดลอกรหัสมีดังนี้:
var str = buffer.toString ("UTF-8"); // สวัสดี
แปลงสตริงเป็นข้อมูลไบนารีภายใต้การเข้ารหัสที่ระบุ:
การคัดลอกรหัสมีดังนี้:
var buffer = ใหม่บัฟเฟอร์ ("สวัสดี", "UTF-8"); // <buffer 68 65 6c 6c 6f>
ความแตกต่างเล็กน้อย:
มีความแตกต่างที่สำคัญระหว่างบัฟเฟอร์และสตริง สตริงเป็นแบบอ่านอย่างเดียวและการปรับเปลี่ยนใด ๆ กับสตริงผลลัพธ์ในสตริงใหม่และสตริงต้นฉบับยังคงไม่เปลี่ยนแปลง
สำหรับบัฟเฟอร์มันเป็นเหมือนอาร์เรย์ภาษา C ที่สามารถดำเนินการตัวชี้ ตัวอย่างเช่นไบต์ที่ตำแหน่งที่แน่นอนสามารถแก้ไขได้โดยตรงในวิธี [ดัชนี]
-
วิธีการชิ้นไม่ได้ส่งคืนบัฟเฟอร์ใหม่ แต่จะส่งคืนตัวชี้ไปยังตำแหน่งที่อยู่ตรงกลางของบัฟเฟอร์ดั้งเดิมดังที่แสดงด้านล่าง
[0x68, 0x65, 0x6c, 0x6c, 0x6f]
-
- -
bin bin.slice (2)
ดังนั้นการปรับเปลี่ยนบัฟเฟอร์ที่ส่งคืนโดยวิธีชิ้นจะดำเนินการกับบัฟเฟอร์ดั้งเดิมเช่น:
การคัดลอกรหัสมีดังนี้:
var buffer = บัฟเฟอร์ใหม่ ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
var sub = bin.slice (2);
sub [0] = 0x65;
console.log (บัฟเฟอร์); // <buffer 68 65 65 6c 6f>
หากคุณต้องการคัดลอกบัฟเฟอร์คุณต้องสร้างบัฟเฟอร์ใหม่ก่อนและคัดลอกข้อมูลในบัฟเฟอร์ดั้งเดิมผ่านวิธี. Copy
สิ่งนี้คล้ายคลึงกับการสมัครสำหรับหน่วยความจำชิ้นใหม่และคัดลอกข้อมูลในหน่วยความจำที่มีอยู่ นี่คือตัวอย่าง
การคัดลอกรหัสมีดังนี้:
var buffer = บัฟเฟอร์ใหม่ ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
var dup = บัฟเฟอร์ใหม่ (bin.length);
buffer.copy (dup);
dup [0] = 0x48;
console.log (บัฟเฟอร์); // <buffer 68 65 6c 6c 6f>
console.log (dup); // <buffer 48 65 65 6c 6f>
ในระยะสั้นบัฟเฟอร์ขยายขีดความสามารถในการประมวลผลข้อมูลของ JS จากสตริงไปจนถึงข้อมูลไบนารีโดยพลการ
ข้างต้นช่วยให้คุณเข้าใจว่าบัฟเฟอร์คืออะไร มาพูดถึงวิธีการใช้และสถานการณ์การใช้งานเฉพาะด้านล่าง
ประการที่สองพูดคุยเกี่ยวกับบัฟเฟอร์
JavaScript เป็นมิตรกับการประมวลผลสตริงและไม่ว่าจะเป็นไบต์ที่กว้างหรือไบต์สตริงเดียวก็ถือว่าเป็นสตริง โหนดจำเป็นต้องประมวลผลโปรโตคอลเครือข่ายฐานข้อมูลการดำเนินงานการประมวลผลรูปภาพการอัปโหลดไฟล์ ฯลฯ และยังต้องประมวลผลข้อมูลไบนารีจำนวนมาก สตริงที่มาพร้อมกับพวกเขาอยู่ไกลจากการปฏิบัติตามข้อกำหนดเหล่านี้ดังนั้นบัฟเฟอร์จึงเข้ามา
โครงสร้างบัฟเฟอร์
บัฟเฟอร์เป็นโมดูลทั่วไปที่รวม JavaScript และ C ++ ส่วนที่เกี่ยวข้องกับประสิทธิภาพจะถูกนำไปใช้ใน C ++ และส่วนที่เกี่ยวข้องกับประสิทธิภาพจะถูกนำไปใช้ใน JavaScript
โหนดถูกติดตั้งลงในหน่วยความจำเมื่อกระบวนการเริ่มต้นและวางลงในวัตถุส่วนกลางดังนั้นจึงไม่จำเป็นต้องต้องการ
วัตถุบัฟเฟอร์: คล้ายกับอาร์เรย์องค์ประกอบของมันเป็นตัวเลขสองหลักในเลขฐานสิบหก
การจัดสรรหน่วยความจำบัฟเฟอร์
การจัดสรรหน่วยความจำของวัตถุบัฟเฟอร์ไม่ได้อยู่ในหน่วยความจำฮีปของ V8 แต่ใช้แอปพลิเคชันหน่วยความจำที่ระดับ C ++ ของโหนด
เพื่อใช้แอปพลิเคชันหน่วยความจำอย่างมีประสิทธิภาพโหนดใช้กลไกการจัดสรรแผ่นซึ่งเป็นกลไกการจัดการหน่วยความจำแบบไดนามิกที่ใช้ระบบปฏิบัติการ *Nix ต่างๆ มีสามสถานะของแผ่น:
(1) เต็ม: สถานะที่จัดสรรอย่างเต็มที่
(2) บางส่วน: สถานะการจัดสรรบางส่วน
(3) ว่าง: ไม่ได้รับมอบหมายสถานะ
การแปลงบัฟเฟอร์
วัตถุบัฟเฟอร์สามารถแปลงเป็นสตริงและประเภทการเข้ารหัสที่รองรับมีดังนี้:
ASCII, UTF-8, UTF-16LE/UCS-2, base64, ไบนารี, hex
สตริงเป็นบัฟเฟอร์
บัฟเฟอร์ใหม่ (Str, [การเข้ารหัส]), UTF-8 เริ่มต้น
buf.write (สตริง, [ออฟเซ็ต], [ความยาว], [การเข้ารหัส])
บัฟเฟอร์เป็นสตริง
buf.tostring ([การเข้ารหัส], [เริ่ม], [end])
ประเภทการเข้ารหัสที่ไม่รองรับโดยบัฟเฟอร์
ตรวจสอบว่ารองรับโดย buffer.isencoding (การเข้ารหัส)
iconv-lite: การใช้งาน JavaScript บริสุทธิ์, เบา, ประสิทธิภาพที่ดีขึ้น, ประสิทธิภาพที่ดีขึ้นโดยไม่ต้องแปลง C ++ เป็น JavaScript
ICONV: เรียกไลบรารี libiconv ใน C ++ เสร็จสมบูรณ์
การประกบกันบัฟเฟอร์
หมายเหตุ "res.on ('data', ฟังก์ชัน (chunk) {})" โดยที่พารามิเตอร์ก้อนเป็นวัตถุบัฟเฟอร์ การใช้การเย็บ + โดยตรงจะถูกแปลงเป็นสตริงโดยอัตโนมัติ สำหรับอักขระไบต์กว้างอาจเกิดรหัสที่อ่านไม่ออก
สารละลาย:
(1) ผ่านเมธอด setEncoding () ในสตรีมที่สามารถอ่านได้วิธีนี้ช่วยให้เหตุการณ์ข้อมูลผ่านวัตถุบัฟเฟอร์ แต่สตริงที่เข้ารหัสและโมดูล StringEncoder ใช้ภายใน
(2) การจัดเก็บวัตถุบัฟเฟอร์ไว้ในอาร์เรย์และในที่สุดก็ประกอบเป็นบัฟเฟอร์ขนาดใหญ่จากนั้นเข้ารหัสลงในเอาต์พุตสตริง
บัฟเฟอร์ใช้กันอย่างแพร่หลายในไฟล์ I/O และเครือข่าย I/O และประสิทธิภาพของมันมีความสำคัญอย่างยิ่งและสูงกว่าสายธรรมดามาก
นอกเหนือจากการสูญเสียประสิทธิภาพของการแปลงสตริงเมื่อใช้บัฟเฟอร์การตั้งค่า Highwatermark มีความสำคัญต่อผลกระทบด้านประสิทธิภาพเมื่ออ่านไฟล์
. การตั้งค่า Highwatermark มีผลกระทบอย่างแน่นอนต่อการจัดสรรและการใช้หน่วยความจำบัฟเฟอร์
ข. การตั้งค่า Highwatermark นั้นเล็กเกินไปซึ่งอาจนำไปสู่การโทรระบบมากเกินไป
เมื่อใดที่ฉันควรใช้บัฟเฟอร์เมื่อใดที่ฉันไม่ควรใช้ ------- จาวาสคริปต์บริสุทธิ์รองรับรหัส Unicode แต่ไม่รองรับไบนารี เมื่อแก้ไขสตรีม TCP หรือสตรีมไฟล์จำเป็นต้องประมวลผลสตรีม เมื่อเราบันทึกสตริงที่ไม่ใช่ UTF-8 แบบไบนารีและรูปแบบอื่น ๆ เราต้องใช้ "บัฟเฟอร์"
3. แนะนำตัวอย่าง
การคัดลอกรหัสมีดังนี้:
var buf = บัฟเฟอร์ใหม่ ("นี่คือการทดสอบข้อความ concat!"), str = "นี่คือการทดสอบข้อความ concat!" -
console.time ("การทดสอบบัฟเฟอร์ concat!");
var list = [];
var len = 100000 * buf.length;
สำหรับ (var i = 0; i <100000; i ++) {
list.push (buf);
len += buf.length;
-
var s1 = buffer.concat (รายการ, len) .tostring ();
console.timeend ("การทดสอบบัฟเฟอร์ concat!");
console.time ("String Concat Test!");
var list = [];
สำหรับ (var i = 100000; i> = 0; i--) {
list.push (str);
-
var s2 = list.oin ("");
console.timeend ("String Concat Test!");
ต่อไปนี้เป็นผลการดำเนินการ:
ความเร็วในการอ่านนั้นเร็วขึ้นอย่างแน่นอนและบัฟเฟอร์ก็ต้องใช้การทำงานของ ToString () ดังนั้นเมื่อเราบันทึกสตริงเรายังต้องใช้สตริง แม้ว่าเราจะแยกสายในสายขนาดใหญ่ความเร็วของสตริงจะไม่ช้ากว่าบัฟเฟอร์
แล้วเราต้องใช้บัฟเฟอร์อีกครั้งเมื่อใด เมื่อไม่มีทางเมื่อเราบันทึกสตริงที่ไม่ใช่ UTF-8 รูปแบบไบนารีและรูปแบบอื่น ๆ เราต้องใช้มัน
สี่มาสรุปกันเถอะ
(1) JavaScript เหมาะสำหรับการประมวลผลข้อมูลที่เข้ารหัส Unicode แต่ไม่เป็นมิตรกับการประมวลผลข้อมูลไบนารี
(2) ดังนั้นเมื่อประมวลผลสตรีม TCP หรือระบบไฟล์จำเป็นต้องประมวลผลสตรีม Octet
(3) โหนดมีวิธีการหลายวิธีในการประมวลผลการสร้างและการใช้สตรีมออคเต็ต
(4) ข้อมูลดิบจะถูกเก็บไว้ในอินสแตนซ์บัฟเฟอร์ บัฟเฟอร์คล้ายกับอาร์เรย์จำนวนเต็ม แต่หน่วยความจำของมันถูกจัดสรรนอกสแต็ก V8 ขนาดของบัฟเฟอร์ไม่สามารถเปลี่ยนแปลงได้
(5), ประเภทการเข้ารหัสที่ประมวลผลคือ: ASCII, UTF8, UTF16LE, UCS2 (นามแฝงสำหรับ UTF16LE), Base64, Binary, Hex
(6) บัฟเฟอร์เป็นองค์ประกอบทั่วโลกและอินสแตนซ์บัฟเฟอร์ได้มาจากบัฟเฟอร์ใหม่โดยตรง ()