Go Event Dispatcher ทำได้เร็วกว่า Channels ถึง 4-10 เท่าด้วยการปรับปรุง Batching

ทีมชุมชน BigGo
Go Event Dispatcher ทำได้เร็วกว่า Channels ถึง 4-10 เท่าด้วยการปรับปรุง Batching

แพ็กเกจ Go ใหม่ได้เกิดขึ้นพร้อมสัญญาว่าจะปฏิวัติการจัดการเหตุการณ์ภายในกระบวนการด้วยการส่งมอบประสิทธิภาพที่เร็วกว่า Go channels แบบดั้งเดิมถึง 4 ถึง 10 เท่า ไลบรารีนี้มุ่งเน้นไปที่การส่งเหตุการณ์ที่มีปริมาณงานสูงและมีความล่าช้าต่ำภายในกระบวนการ Go เดียว ทำให้เกิดการอภิปรายเกี่ยวกับการแลกเปลี่ยนระหว่างประสิทธิภาพและฟังก์ชันการทำงานในการเขียนโปรแกรมแบบ concurrent

เกณฑ์มาตรฐานประสิทธิภาพ (13th Gen Intel i7-13700K)

การกำหนดค่า เวลา/การดำเนินการ การดำเนินการ/วินาที ความเร็วเทียบกับ Channels
1x1 38.7 ns 25.9M +4.2x
1x10 13.0 ns 77.1M +12x
1x100 12.2 ns 81.7M +7.7x
10x1 26.5 ns 37.7M +6.3x
10x10 12.2 ns 82.3M +7.8x
10x100 12.2 ns 82.0M +6.6x

ประสิทธิภาพผ่านกลยุทธ์ Smart Batching และ Locking

การปรับปรุงความเร็วที่น่าประทับใจมาจากแนวทางสถาปัตยกรรมที่ชาญฉลาดซึ่งแตกต่างอย่างมากจากวิธีการทำงานของ Go channels แทนที่จะประมวลผลเหตุการณ์ทีละรายการ dispatcher จะจัดกลุ่ม consumers ตามประเภทเหตุการณ์และใช้ lock เดียวต่อกลุ่ม เมื่อเผยแพร่เหตุการณ์ มันจะใช้ lock ครั้งเดียวและทำซ้ำเหตุการณ์ไปยังคิวของ consumer แต่ละตัว ทำให้ consumers สามารถประมวลผลเหตุการณ์ได้ถึง 128 รายการต่อการดำเนินการ lock หนึ่งครั้ง

กลยุทธ์ batching นี้ลดค่าใช้จ่ายที่ channels มักจะเผชิญ โดยที่แต่ละ channel ต้องการ lock ของตัวเองและประมวลผลเพียงหนึ่งองค์ประกอบในแต่ละครั้ง ผลลัพธ์คือการดำเนินการ lock และ unlock ที่น้อยลงอย่างมาก นำไปสู่การเพิ่มประสิทธิภาพอย่างมากที่สังเกตได้ใน benchmarks

คุณสมบัติทางเทคนิคที่สำคัญ

กลยุทธ์การจัดกลุม: ประมวลผลได้สูงสุด 128 เหตุการณ์ต่อรอบการล็อค/ปลดล็อค • การล็อคแบบกลุม: ใช้ล็อคเดียวต่อกลุ่มประเภทเหตุการณ์แทนการล็อคต่อช่องทาง • ไม่มีการจัดสรรหน่วยความจำ: ผลการทดสอบแสดง 0 allocs/op ในทุกการกำหนดค่าการทดสอบ • การประมวลผลแบบอะซิงโครนัส: ผู้สมัครสมาชิกแต่ละรายทำงานใน goroutine ของตัวเอง • อินเทอร์เฟซแบบ Generic: ทำงานได้กับทุกประเภทที่ใช้งาน Event interface

Trade-offs และข้อจำกัดที่ทำให้เกิดการอภิปรายของนักพัฒนา

การเพิ่มประสิทธิภาพมาพร้อมกับข้อพิจารณาสำคัญที่นักพัฒนากำลังอภิปรายกันอย่างแข็งขัน การใช้งานนี้ใช้การ polling บ่อยครั้งเพื่อรักษาข้อมูลเมตาของกลุ่ม ซึ่งอาจมีประสิทธิภาพน้อยกว่าในสถานการณ์ที่มีปริมาณงานต่ำซึ่งการใช้งาน CPU ควรลดลงเป็นศูนย์ในช่วงที่ไม่มีการทำงาน สิ่งนี้ทำให้ dispatcher เหมาะสำหรับแอปพลิเคชันที่มีปริมาณงานสูง แต่อาจเป็นการสิ้นเปลืองสำหรับ workloads ที่เบา

สมาชิกในชุมชนได้สังเกตว่าการเปรียบเทียบ event dispatcher เฉพาะทางนี้กับ Go channels นั้นไม่ค่อยยุติธรรมนัก เนื่องจาก channels ให้บริการวัตถุประสงค์ที่กว้างขึ้นนอกเหนือจากการ broadcasting เหตุการณ์อย่างง่าย Channels ให้กลไกการแบ่งปันหน่วยความจำพร้อมกับการ blocking, buffering และการจัดการ backpressure ในตัว ซึ่งเป็นคุณสมบัติที่ dispatcher นี้ตั้งใจละเว้นเพื่อความเร็ว

กรณีการใช้งานที่เหมาะสมเทียบกับข้อจำกัด

เหมาะสำหรับ: • การแยกโมดูลภายในกระบวนการ Go เดียว • การส่งอีเวนต์ที่มีปริมาณงานสูงและมีความหน่วงต่ำ • รูปแบบ pub/sub ที่เบา • โซลูชันที่ไม่ต้องพึ่งพาไลบรารีภายนอก

ไม่เหมาะสำหรับ: • การสื่อสารระหว่างกระบวนการ/เซอร์วิส • การเก็บรักษาหรือความคงทนของอีเวนต์ • การกำหนดเส้นทางและการกรองขั้นสูง • การดำเนินการ subscribe/unsubscribe ที่หนัก • สถานการณ์ข้ามภาษา/แพลตฟอร์ม

การใช้งานในโลกจริงและกรณีการใช้งาน

ไลบรารีนี้ได้พบการใช้งานจริงแล้ว โดยนักพัฒนาใช้มันในการพัฒนาเกมผู้เล่นหลายคนและสถานการณ์อื่นๆ ที่ต้องการการสื่อสารภายในกระบวนการอย่างรวดเร็ว Dispatcher มีความเป็นเลิศในสถานการณ์ที่โมดูลต้องการการแยกตัวภายในกระบวนการเดียว ต้องการรูปแบบ pub/sub ที่เบา และการจัดการเหตุการณ์ที่มีปริมาณงานสูงเป็นสิ่งสำคัญ

อย่างไรก็ตาม มันไม่เหมาะสำหรับการสื่อสารระหว่างกระบวนการ การเก็บรักษาเหตุการณ์ หรือสถานการณ์ที่ต้องการการ routing และการกรองขั้นสูง การมุ่งเน้นยังคงอยู่ที่ความเร็วและความเรียบง่ายสำหรับกรณีการใช้งานเฉพาะมากกว่าการเป็นทางเลือกทั่วไปสำหรับโซลูชันการส่งข้อความที่มีอยู่

การเกิดขึ้นของ event dispatcher เฉพาะทางนี้เน้นย้ำแนวโน้มที่กำลังดำเนินอยู่ในการพัฒนา Go ที่นักพัฒนากำลังสร้างไลบรารีที่มุ่งเน้นซึ่งเสียสละฟังก์ชันการทำงานทั่วไปเพื่อการเพิ่มประสิทธิภาพอย่างมากในสถานการณ์เฉพาะ เมื่อแอปพลิเคชันต้องการประสิทธิภาพที่สูงขึ้นเรื่อยๆ การปรับปรุงที่มีเป้าหมายเช่นนี้กำลังกลายเป็นสิ่งที่มีค่าเพิ่มขึ้นสำหรับนักพัฒนาที่สามารถทำงานภายในข้อจำกัดของมัน

อ้างอิง: Fast, In-Process Event Dispatcher