bench, pprof, escape, Pool, PGO
CGO_ENABLED=0 ไปเลยเล็กสุดjson/v2 มาใส่ให้แล้ว ไม่ต้องแก้โค้ดก็เร็วขึ้นอย่าเดา ให้ดูกราฟก่อนแก้ 90% ของความช้ามาจาก 10% ของโค้ด
Stack = ลิ้นชักเร็ว, Heap = โกดังช้าต้องให้ GC เก็บ Go เลือกให้เอง (escape analysis):
ทริกบ้านๆ ลดหนี:
sync.Pool reuse ของแพง (buffer) แทนสร้างทิ้ง//go:fix inline ให้ go fix ช่วยไล่simd/archsimd (ทดลอง 1.26): สั่ง CPU ทำหลายเลขพร้อมกัน เหมาะสายภาพ/เสียง/AI รู้ชื่อไว้พอMarshal/Unmarshal เดิมได้เลย 1.27 เร็วขึ้นเอง อยากซิ่งค่อยไป json/v2 (ตั้งค่าได้) + jsontext (สตรีมไฟล์ยักษ์)net/http ธรรมดา netpoller ช่วยรอเน็ตโดยไม่กิน thread อยู่แล้ว อย่าเขียน loop รอเองgo mod tidy แล้ววัดใหม่ (อาจเร็วขึ้นเฉยๆ)go test -bench + pprof flame หาแท่งกว้างสุด-gcflags='-m' ดู escape แปลกๆ-race ต้องผ่านก่อนจูน ไม่งั้นยิ่งแก้ยิ่งพังอ้างอิง: Go 1.26 (Green Tea, cgo -30%, stack alloc, pprof flame default, simd), Go 1.27 (json/v2)
func BenchmarkJoin(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_ = strings.Join(words, ",")
}
}var sb strings.Builder
sb.Grow(1024) // จองก่อนถ้ารู้ขนาดคร่าวๆ
for _, w := range words {
sb.WriteString(w)
}
s := sb.String()var bufPool = sync.Pool{
New: func() any { return new(bytes.Buffer) },
}
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()
defer bufPool.Put(buf) // คืนถัง ใช้ซ้ำไม่ต้อง new บ่อยbench + pprof) อย่าเดาว่าช้าตรงไหน-benchmem (allocs) ก่อนดูเวลา alloc เยอะ = GC เหนื่อยstrings.Builder แทน += ใน loop, Grow ถ้ารู้ขนาด+= vs Builder ดูว่า allocs ต่างกันกี่เท่า