
Go Serialization 01: สร้าง JSON baseline ที่เปรียบเทียบได้
บทแรกเราจะได้ baseline ที่เชื่อถือได้ครับ เป้าหมายคือให้ทุก format ใช้ข้อมูลเดียวกันและคืนข้อมูลครบ ก่อนเริ่มถามว่าใครเร็วกว่า
เตรียมโปรเจกต์
ดาวน์โหลด โปรเจกต์ Go พร้อม schemas, generated code, tests และผลดิบ แล้วแตกไฟล์ ใช้ Go 1.27 ขึ้นไป เปิด terminal ในโฟลเดอร์ go-api-serialization และรัน go mod download ครั้งแรก ไม่ต้องติดตั้ง compiler ของ schema เพื่อเริ่มเรียน
โค้ดบนหน้านี้เป็นตัวอย่างบางส่วน (fragment) เพื่ออธิบายจุดสำคัญ คำสั่ง shell ตรวจ syntax ส่วน โปรเจกต์เต็มตรวจด้วย go test ./... ใน quality gate ไม่ควรนำ fragment ไปรันเป็นโปรแกรมเดี่ยว
1. เข้าใจข้อมูลที่กำลังวัด
เปิด catalog.go แล้วดู Fixture(n) ซึ่งสร้างสินค้าแบบ deterministic: เรียกด้วยจำนวนเท่าเดิมจะได้ข้อมูลเท่าเดิม ชื่อมีภาษาไทย ราคาใช้หน่วยย่อยจำนวนเต็ม และ tags มีข้อความซ้ำที่ gzip น่าจะบีบได้ดี จึงไม่ควรนำผลขนาดนี้ไปทำนายข้อมูลสุ่มหรือภาพถ่าย
ตัวอย่างบางส่วนของแบบจำลองข้อมูล:
type Product struct {
ID int64 `json:"id" msgpack:"id" avro:"id"`
Name string `json:"name" msgpack:"name" avro:"name"`
PriceCents int64 `json:"price_cents" msgpack:"price_cents" avro:"price_cents"`
InStock bool `json:"in_stock" msgpack:"in_stock" avro:"in_stock"`
Tags []string `json:"tags" msgpack:"tags" avro:"tags"`
}
Fixture(1) มี ID 1 ราคา 12500 และ stock เป็น false ชื่อเริ่มด้วย “ต้นไม้ริมหน้าต่าง” เรา normalize nil slices เป็น empty slices เพื่อให้การเปรียบเทียบไม่พังเพราะรูปแบบเก็บค่าเริ่มต้นต่างกัน
2. ตรวจความถูกต้องก่อนจับเวลา
go test -run 'TestRoundTrip/json' -v
go run ./cmd/sizes
ผลที่ตรวจได้: tests ผ่านทั้งข้อมูลว่าง ภาษาไทย emoji และค่า int64 ขอบบน คำสั่ง sizes แสดง CSV ที่มี 15 แถวข้อมูล: 5 รูปแบบ × 3 จำนวน ขนาดเป็น bytes จริง ไม่ใช่จำนวนตัวอักษรไทย
3. วัด JSON baseline
go test -run '^$' -bench 'BenchmarkCodecs/json' -benchmem -benchtime=300ms -count=5
อ่าน ns/op เป็นเวลาต่อ operation, B/op เป็น bytes ที่ allocate และ allocs/op เป็นจำนวน allocation การเตรียม fixtures อยู่นอก loop แต่ validation และการสร้าง Go object อยู่ในงานที่วัด decode จะคืนสินค้าและ tags ทุกชิ้น
อย่าใช้ MB/s ของแต่ละ format เป็นอันดับความเร็ว เพราะตัวหารของแต่ละแถวคือขนาด wire ของ format นั้นเอง ให้เทียบ ns/op สำหรับงานที่ให้ผลเท่ากัน
แบบฝึกหัด
เปลี่ยนชื่อสินค้าเป็นข้อความยาวขึ้นใน Fixture รัน tests แล้วเก็บไฟล์ sizes อีกชุด เปรียบเทียบ raw bytes กับ gzip bytes อธิบายว่าความซ้ำของข้อความทำให้ผลต่างจากข้อความสุ่มอย่างไร จากนั้นคืน fixture ก่อนนำผลไปเทียบกับบทถัดไป