Go 1.27 แยกทางด่วนให้ Allocation ก้อนเล็ก: เร็วขึ้นโดยไม่ต้องแก้โค้ด
โปรแกรม Go จำนวนมากสร้าง object เล็ก ๆ ซ้ำทั้งวัน เช่น node, closure หรือ struct ชั่วคราว ก่อน Go 1.27 ก้อนเหล่านี้วิ่งผ่านเส้นทางจัดสรรทั่วไปที่ต้องคำนวณ span class และทำงานประกอบหลายขั้น ทีม Go อธิบายเมื่อ 16 กันยายน ว่า runtime ใหม่แยกฟังก์ชันตามขนาดยอดนิยมไว้ล่วงหน้า คล้ายซูเปอร์มาร์เก็ตเปิดช่องด่วนให้ตะกร้าเล็กครับ
ผลที่ทีม Go วัดคือ allocation ต่ำกว่า 80 ไบต์เร็วขึ้นราว 20–30% และโปรแกรมที่หนักด้าน allocation อาจเร็วขึ้นประมาณ 1% จุดสำคัญคือเราไม่ต้องเปลี่ยน source code หรือเลือก API ใหม่ compiler กับ runtime จัดเส้นทางให้เอง ส่วนก้อนใหญ่หรือขนาดที่ไม่เหมาะกับทางเฉพาะยังกลับไปทางทั่วไป
ตัวอย่างนี้ตรวจพฤติกรรมที่โค้ดพึ่งพา—ก้อนใหม่มีขนาดและข้อมูลถูกต้อง—ไม่ได้แกล้งทำเป็น benchmark ข้ามเครื่องครับ
package allocation
import "testing"
type Event struct {
Kind byte
Count uint32
}
func cloneEvents(src []Event) []Event {
dst := make([]Event, len(src))
copy(dst, src)
return dst
}
func TestCloneEventsOwnsItsStorage(t *testing.T) {
src := []Event{{Kind: 1, Count: 3}, {Kind: 2, Count: 5}}
dst := cloneEvents(src)
dst[0].Count = 99
if src[0].Count != 3 || len(dst) != 2 {
t.Fatalf("unexpected clone: src=%v dst=%v", src, dst)
}
}
สิ่งที่ควรทำกับ production
อัปเกรด toolchain แล้ววัด workload เดิมด้วย go test -bench และ profile ก่อนสรุป เพราะเปอร์เซ็นต์จาก runtime เป็นค่าเฉลี่ย ไม่ใช่สัญญาว่าทุก service จะดีขึ้นเท่ากัน งานที่รอฐานข้อมูลหรือ network แทบไม่เห็นความต่าง ขณะที่ parser หรือ serializer ที่สร้าง object จิ๋วจำนวนมากมีโอกาสเห็นชัดกว่า
อย่าใช้ข่าวนี้เป็นเหตุผลสร้าง allocation เพิ่ม การ reuse buffer, ลด escape และออกแบบ lifetime ให้ชัดยังสำคัญเหมือนเดิม ทางด่วนทำให้ค่าผ่านด่านถูกลง แต่ไม่ทำให้รถล้านคันหายไป นอกจากนี้ benchmark ที่เก็บผลลัพธ์ไม่อยู่จริงอาจถูก compiler ตัดทิ้ง ควรตรวจ -benchmem, profile และ latency ปลายทางร่วมกัน
Recap
- Go 1.27 เร่ง allocation ก้อนเล็กใน runtime โดย source เดิมใช้ประโยชน์ได้
- ตัวเลข 20–30% เป็นระดับ operation; ผลทั้งแอปขึ้นกับสัดส่วนงาน
- benchmark workload จริงและดู allocation count ควบคู่ latency
- ยังลด allocation ที่ไม่จำเป็นเหมือนเดิมครับ