Benchmarks
JavaScript benchmarking vs Go benchmarking
หัวข้อที่มีชื่อว่า “JavaScript benchmarking vs Go benchmarking”ใน JavaScript คุณใช้ console.time / console.timeEnd เวลาอยากวัดแบบเร็ว ๆ หรือใช้ benchmark.js สำหรับ micro-benchmark ที่รัดกุมทางสถิติ ทั้งสองตัวรันอยู่นอก test runner และต้องตั้งค่าแยกต่างหาก
ใน Go benchmark อยู่ในไฟล์ _test.go เดียวกับ unit test คุณรันด้วยคำสั่ง go test เดิม — แค่เพิ่ม flag เข้าไป toolchain จัดการ statistical warmup ให้อัตโนมัติ
หมายเหตุเรื่อง Playground: benchmark ต้องรันใน binary context ของ
go test -benchบล็อกโค้ดด้านล่างคือไฟล์ benchmark จริง — รันบนเครื่องคุณ
Signature ของ benchmark function
หัวข้อที่มีชื่อว่า “Signature ของ benchmark function”// JavaScript — benchmark.js (ไลบรารีภายนอก)import Benchmark from 'benchmark';
const suite = new Benchmark.Suite();suite .add('sum-loop', () => { let total = 0; for (let i = 0; i < 1000; i++) total += i; }) .on('complete', function () { console.log(this[0].toString()); }) .run();// Go — built-in ใน testing package// sum_test.gopackage main
import "testing"
func sum(n int) int { total := 0 for i := 0; i < n; i++ { total += i } return total}
func BenchmarkSum(b *testing.B) { for b.Loop() { // Go 1.24+: b.Loop() เป็น form ที่แนะนำ sum(1000) }}การรัน benchmarks
หัวข้อที่มีชื่อว่า “การรัน benchmarks”# รัน benchmarks ทั้งหมดใน package ปัจจุบันgo test -bench=. ./...
# รัน benchmarks ที่ match regexgo test -bench=BenchmarkSum ./...
# รัน unit tests ควบคู่ไปกับ benchmarks ด้วยgo test -bench=. -run=. ./...
# ข้าม unit tests (รันเฉพาะ benchmarks)go test -bench=. -run='^$' ./...
# ควบคุมเวลา benchmark (default 1s)go test -bench=. -benchtime=5s ./...
# รายงาน memory allocationsgo test -bench=. -benchmem ./...อ่าน benchmark output
หัวข้อที่มีชื่อว่า “อ่าน benchmark output”BenchmarkSum-8 14253187 84.23 ns/opBenchmarkSum-8 14253187 84.23 ns/op 0 B/op 0 allocs/op| คอลัมน์ | ความหมาย |
|---|---|
BenchmarkSum-8 | ชื่อ Benchmark + GOMAXPROCS (จำนวน CPU) |
14253187 | จำนวน iterations (b.N) ที่ runner เลือก |
84.23 ns/op | Nanoseconds ต่อ operation |
0 B/op | Bytes ที่ allocate ต่อ operation (-benchmem) |
0 allocs/op | Heap allocations ต่อ operation (-benchmem) |
Go runner จะค่อย ๆ เพิ่ม b.N จนผลลัพธ์นิ่งทางสถิติ — คุณไม่ต้อง hardcode จำนวน iteration เอง
เปรียบเทียบ implementations
หัวข้อที่มีชื่อว่า “เปรียบเทียบ implementations”package strings_test
import ( "strings" "testing")
func BenchmarkConcatPlus(b *testing.B) { for b.Loop() { var s string for i := 0; i < 100; i++ { s += "x" // allocates ทุก iteration } _ = s }}
func BenchmarkConcatBuilder(b *testing.B) { for b.Loop() { var sb strings.Builder for i := 0; i < 100; i++ { sb.WriteByte('x') // single pre-allocated buffer } _ = sb.String() }}รันด้วย -benchmem เพื่อดูว่า allocation ต่างกันมากแค่ไหน:
BenchmarkConcatPlus-8 228468 5213 ns/op 5440 B/op 99 allocs/opBenchmarkConcatBuilder-8 2134500 562 ns/op 128 B/op 1 allocs/opProfiling ระหว่าง benchmarks
หัวข้อที่มีชื่อว่า “Profiling ระหว่าง benchmarks”# เขียน CPU profile ขณะ benchmarkgo test -bench=BenchmarkSearch -cpuprofile=cpu.out ./...
# เขียน heap (memory) profilego test -bench=BenchmarkSearch -memprofile=mem.out ./...
# เปิด profile ใน interactive pprof toolgo tool pprof cpu.outเครื่องมือ pprof จะลงลึกในบทเรียน pprof Profiling