Pengenalan sync.Pool
sync.Pool
sering kita dengar saat implementasi design patter yaitu bernama Object Pool Pattern. Pool adalah sekumpulan objek sementara yang dapat disimpan dan diambil secara individual. Sebuah Pool aman untuk digunakan oleh beberapa goroutine secara bersamaan.
sync.Pool
memungkinkan kita untuk menggunakan kembali memori tanpa mengalokasikan. Juga jika kita memiliki server http
yang menunggu request POST
dengan body json
dan harus melakukan decode
ke dalam struktur, maka kamu bisa menggunakan sync.Pool
untuk menghemat memory dan mengurangi waktu response dari server.
Kenapa kita harus menggunakan sync.Pool
?
Tujuan Pool
adalah untuk penyimpanan item sementara yand dialokasikan tetapi tidak terpakai untuk digunakan kembali sehingga mengurangi pengumpulan dari garbage collactor
.
Penggunaan Pool
yang tepat memang digunakanuntuk mengelola sekelompok item sementara yang dibagikan dan bisa digunakan kembali oleh client secara independen.
Hal yang terpenting yang perlu kita catat bahwa Pool
memiliki cost
untuk performanya sendiri. Jau lebih lambat untuk menggunakan sync.Pool
dari pada inisialisasi sederhana.
Penggunaan
sync.Pool
memberikan beberapa method yang sudah disediakan diantaranya:
Get()
digunakan untuk mengambil data dariPool
, lalu menghapusnya dari Pool tersebut dan mengembalikan data yang telah diambilnya.Put(x any)
digunakan untuk menyimpan data ke dalamPool
yang sudah kita inisialisasi.
Implementasi dan sampel sync.Pool
Sekarang kita akan coba bagaimana simpelnya mengimplementasikan sync.Pool
. Pertama, kita akan menggunakan sync.Pool
diaman kita akan menjadikan suatu fungsi yang melakukan generate suatu objek dan mengembalikan data ketika akan dipanggil.
package main
import (
"fmt"
"sync"
)
type Person struct {
Name string
}
var pool = sync.Pool{
New: func() any {
fmt.Println("Creating a new person...")
return &Person{}
},
}
func main() {
person := pool.Get().(*Person)
fmt.Println("Get object from sync.Pool for the first time:", person)
fmt.Println("Put the object back in the pool")
pool.Put(person)
person.Name = "Gopher"
fmt.Println("Set object property name:", person.Name)
fmt.Println("Get object from pool again (it's updated):", pool.Get().(*Person))
fmt.Println("There is no object in the pool now (new one will be created):", pool.Get().(*Person))
}
Dan jika kita jalankan, kita akan melihat outputnya seperti dibawah ini:
$ go run main.go
Creating a new person...
Get object from sync.Pool for the first time: &{}
Put the object back in the pool
Set object property name: Gopher
Get object from pool again (it's updated): &{Gopher}
Creating a new person...
There is no object in the pool now (new one will be created): &{}
Kesimpulan
Perhatikan kita tahu bagaiman ketika kita mengeluarkan data tersebut dari Pool
maka akan menghilang didalam Pool
tersebut sehingga ini cocok digunakan untuk menyimpan beberapa objek sementara yang dibagikan diantara goroutine.