Published on

Membuat Benchmark di Golang

Authors

Ketika membuat suatu aplikasi tidak dipungkiri salah satu faktor yang sangat penting yaitu kecepatan. Baik kecepatan load data, kecepatan dalam menjalankan suatu perintah ataupun ketika membuka dan menutup aplikasi. Tentunya perlu instrument untuk mengetahui seberapa cepat kode kita, dalam hal ini perasaan tidak dapat digunakan sebagai tolak ukur. Menariknya pada bahasa pemrograman golang sudah ada library standar untuk mengukur seberapa cepat perintah dalam kode yang sering disebut benchmarking.

Kali ini contoh kasus untuk komparasi performa saya menggunakan 2 sorting sederhana yaitu bubble sort dan shell sort. Kira-kira mana yang lebih cepat ya? Ah iya, jangan pake perasaan tapi pake hasil benchmark untuk menentukan siapa yang paling cepat. Berikut contoh 2 sorting tersebut.


_40
// sort.go
_40
package benchmark
_40
_40
import "math/rand"
_40
_40
// BubbleSort sorting array of integer using bubble sort
_40
func BubbleSort(arr []int) []int {
_40
tmp := 0
_40
for i := 0; i < len(arr); i++ {
_40
for j := 0; j < len(arr)-1-i; j++ {
_40
if arr[j] > arr[j+1] {
_40
tmp = arr[j]
_40
arr[j] = arr[j+1]
_40
arr[j+1] = tmp
_40
}
_40
}
_40
}
_40
return arr
_40
}
_40
_40
// ShellSort sorting int using shell sort
_40
func ShellSort(arr []int) []int {
_40
for d := int(len(arr) / 2); d > 0; d /= 2 {
_40
for i := d; i < len(arr); i++ {
_40
for j := i; j >= d && arr[j-d] > arr[j]; j -= d {
_40
arr[j], arr[j-d] = arr[j-d], arr[j]
_40
}
_40
}
_40
}
_40
return arr
_40
}
_40
_40
// RandArray helper for create random array
_40
func RandArray(n int) []int {
_40
arr := make([]int, n)
_40
for i := 0; i <= n-1; i++ {
_40
arr[i] = rand.Intn(n)
_40
}
_40
return arr
_40
}

Pada artikel sebelumnya tentang Unit Test sudah dibahas tentang bagaimana caranya membuat unit test pada suatu package, penggunaan benchmark juga tetap menggunakan package testing namun menggunakan variabel B bukan T seperti yg digunakan pada Unit Test. Langsung saja pada penggunaanya dalam kode berikut.


_21
package benchmark_test
_21
_21
import (
_21
"testing"
_21
_21
"github.com/h4ckm03d/blog-codes/golang101/benchmark"
_21
)
_21
_21
func BenchmarkBubbleSorting(b *testing.B) {
_21
arr := benchmark.RandArray(100)
_21
for n := 0; n < b.N; n++ {
_21
benchmark.BubbleSort(arr)
_21
}
_21
}
_21
_21
func BenchmarkShellSorting(b *testing.B) {
_21
arr := benchmark.RandArray(100)
_21
for n := 0; n < b.N; n++ {
_21
benchmark.ShellSort(arr)
_21
}
_21
}

Untuk menjalankan benchmark sama dengan unit test, hanya saja menggunakan parameter tambahan -bench=. untuk semua benchmark. Jika ingin menjalankan salah satu bisa menggunakan -bench=ShellSort, menggunakan nama fungsi benchmark tanpa menggunakan kata Benchmark. Berikut hasil benchmark dari 2 fungsi sorting diatas.


_16
➜ benchmark git:(master) ✗ go test -bench=.
_16
goos: darwin
_16
goarch: amd64
_16
pkg: github.com/h4ckm03d/blog-codes/golang101/benchmark
_16
BenchmarkBubbleSorting-12 300000 4181 ns/op
_16
BenchmarkShellSorting-12 3000000 433 ns/op
_16
PASS
_16
ok github.com/h4ckm03d/blog-codes/golang101/benchmark 3.049s
_16
➜ benchmark git:(master) ✗ go test -bench=BubbleSort
_16
goos: darwin
_16
goarch: amd64
_16
pkg: github.com/h4ckm03d/blog-codes/golang101/benchmark
_16
BenchmarkBubbleSorting-12 300000 4188 ns/op
_16
PASS
_16
ok github.com/h4ckm03d/blog-codes/golang101/benchmark 1.306s
_16
➜ benchmark git:(master) ✗

Pada hasil perintah go test -bench=. diatas menghasilkan 3 kolom:

  1. Nama benchmark, contohnya BenchmarkBubbleSorting-12

  2. Total operasi yg dijalankan, 300000

  3. waktu yang dibutuhkan untuk menjalankan 1 fungsi dalam nanoseconds. 4181 ns/op

Jadi BubbleSort perlu 4181 ns/op dan ShellSort memerlukan 433 ns/op. Sudah jelas kalau pemenangnya adalah ShellShort. Mudah bukan?

Sampai jumpa lagi di tulisan selanjutnya.

Code lengkapnya ada di github