diskusi.tech (beta) Community

loading...
Lentera Community

Secepat apa kodemu?

upi profile image Moch Lutfi Originally published at lumochift.org ・3 min read

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.

// sort.go
package benchmark

import "math/rand"

// BubbleSort sorting array of integer using bubble sort
func BubbleSort(arr []int) []int {
    tmp := 0
    for i := 0; i < len(arr); i++ {
        for j := 0; j < len(arr)-1-i; j++ {
            if arr[j] > arr[j+1] {
                tmp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = tmp
            }
        }
    }
    return arr
}

// ShellSort sorting int using shell sort
func ShellSort(arr []int) []int {
    for d := int(len(arr) / 2); d > 0; d /= 2 {
        for i := d; i < len(arr); i++ {
            for j := i; j >= d && arr[j-d] > arr[j]; j -= d {
                arr[j], arr[j-d] = arr[j-d], arr[j]
            }
        }
    }
    return arr
}

// RandArray helper for create random array
func RandArray(n int) []int {
    arr := make([]int, n)
    for i := 0; i <= n-1; i++ {
        arr[i] = rand.Intn(n)
    }
    return arr
}
Enter fullscreen mode Exit fullscreen mode

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.

package benchmark_test

import (
    "testing"

    "github.com/h4ckm03d/blog-codes/golang101/benchmark"
)

func BenchmarkBubbleSorting(b *testing.B) {
    arr := benchmark.RandArray(100)
    for n := 0; n < b.N; n++ {
        benchmark.BubbleSort(arr)
    }
}

func BenchmarkShellSorting(b *testing.B) {
    arr := benchmark.RandArray(100)
    for n := 0; n < b.N; n++ {
        benchmark.ShellSort(arr)
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

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

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?

Tapi jika masih belum puas dengan hasil benchmarknya, bagaimana cara mengetahui memory yang dipakai? Kita hanya perlu menambahkan flag -benchmem.

Berikut contoh outputnya:

go test -bench=. -benchmem          
goos: darwin
goarch: amd64
pkg: github.com/h4ckm03d/blog-codes/golang101/benchmark
BenchmarkBubbleSorting-4          253015              4433 ns/op               0 B/op          0 allocs/op
BenchmarkShellSorting-4          2425978               489 ns/op               0 B/op          0 allocs/op
PASS
ok      github.com/h4ckm03d/blog-codes/golang101/benchmark      2.885s
Enter fullscreen mode Exit fullscreen mode

Dengan -benchmem terlihat alokasi memory tiap operasi dan berapa Byte yg dipakai. Kebetulan zero allocation untuk kedua fungsi diatas. Sebenarnya masih banyak kesaktian golang untuk mencari tahu lebih dalam tentang kode kita seperti cpu dan memory profiling. Mungkin akan dibahas ditulisan lain. Semoga bermanfaat. Code lengkapnya ada di github

Discussion

pic
Editor guide