Golang

มาถึงการทำ Benchmark ของ Go กันบ้าง
เพิ่งรู้มาว่า Go มันได้เตรียมการทำ Benchmark
เพื่อให้วัดประสิทธิภาพการทำงานของ code
ที่เขียนขึ้นมาว่าเป็นอย่างไร
ดังนั้นมาลองวัดกันดูดีไหม

โดยตัวอย่างที่จะเอามาทดสอบเพื่อวัด Benchmark คือ Fibonacci
เนื่องจากมันใกล้ตัวดี
ซึ่งสามารถเขียน code ด้วย Go แบบง่ายๆ ได้ดังนี้

ต่อจากนั้นสร้าง test สำหรับทดสอบ Benchmark ดังนี้

คำอธิบาย
การเขียนจะคล้ายกับการเขียน test ปกติที่อยู่ใน package testing แต่สิ่งที่แตกต่างก็คือ
1. ชื่อ function ขึ้นต้นด้วยคำว่า Benchmark นะ ไม่ใช่ Test

2. โดย function ที่ขึ้นต้นด้วยคำว่า Benchmark จะถูกทำการทดสอบ
และสั่งให้ทำงานตามค่าของ b.N
และจะเพิ่มขึ้นไปเรื่อยๆ จนกว่าตัวจัดการ benchmark
จะได้ค่าที่พอใจหรือค่าที่เสถียรที่สุดนั่นเอง

3.  จำนวนรอบการทดสอบคือ b.N รอบ ดังนั้น
ในทุกๆ  benchmark จะต้องมี loop for แบบนี้เสมอ

ทำการสั่งให้เริ่มต้นการวัด Benchmark ด้วยคำสั่ง

go test -bench=.

หรือสามารถระบุ test ที่ต้องการดังนี้

go test -bench=Fibonacci5

ผลการทำงานเป็นดังนี้

PASS
BenchmarkFibonacci5     50000000             77.9 ns/op

คำอธิบาย
จำนวนลูบที่ทำงาน 50,000,000 รอบ โดยแต่ละรอบใช้เวลา 77.9 nanosecond

ถ้าต้องการทดสอบหลายๆ ตัวสามารถเขียน code
สำหรับการทำ benchmark ใหม่ได้ดังนี้

แล้วทำการทดสอบใหม่ ได้ผลการทำงานดังนี้

PASS
BenchmarkFibonacci1     500000000              4.34 ns/op
BenchmarkFibonacci3     100000000             16.8 ns/op
BenchmarkFibonacci5     50000000             77.6 ns/op
BenchmarkFibonacci7     10000000            205 ns/op
BenchmarkFibonacci10      2000000           1007 ns/op
BenchmarkFibonacci20        10000         120881 ns/op
BenchmarkFibonacci30          100       13419333 ns/op
BenchmarkFibonacci40            1     1904710498 ns/op

คำอธิบาย
ในแต่ละ benchmark function นั้นจะทำงานอย่างนั้น 1 วินาทีเสมอ
แต่ถ้าผลการทำงานเร็วกว่า 1 วินาที แล้ว
ตัววัด benchmark จะทำการเพิ่มค่าของ b.B ขึ้นไปเรื่อย
ซึ่งเพิ่มในลักษณะแบบ exponential กันเลย คือ 1, 2, 5, 10, 20, 50 เป็นต้น

สังเกต BenchmarkFibonacci40 ได้ว่าทำการทดสอบเพียง 1 ครั้ง เพราะว่าทำงานนานกว่า1 วินาทีนั่นเอง
แต่ถ้าอยากเพิ่มจาก 1 วินาทีเป็น 20 วินาทีสามารถทำได้ด้วยการเพิ่ม -benchtime=20s เข้าไป
ดังตัวอย่าง ทำการ run เฉพาะ BenchmarkFibonacci40 เท่านั้น

go test -bench=Fibonacci40 -benchtime=20s

ผลการทำงาน

PASS
BenchmarkFibonacci40           20     1744522251 ns/op

จะเห็นได้ว่า เราสามารถทำการวัดประสิทธิภาพของ code
ที่เราทำการพัฒนาขึ้นมาได้ ว่าเป็นไปตามที่เราต้องการหรือไม่
และสามารถวัดด้วยการใช้ package testing ที่ Go เตรียมไว้ให้ได้ทันที
รวมทั้งเรายังใช้เครื่องมือนี้ ช่วยให้เราปรับปรุงประสิทธิภาพของ code
อยู่อย่างเสมอ เนื่องจากสามารถทำซ้ำได้ตามที่ต้องการเลย
ชีวิตของ programmer น่าจะสะดวกมากยิ่งขึ้นนะครับ

ตัวอย่าง code อยู่ที่ Github :: Go benchmark