Lompat ke konten Lompat ke sidebar Lompat ke footer

Golang Concurrency #18

Berikut adalah contoh lain yang efisien menggunakan concurrency untuk melakukan parallel sum (menghitung jumlah total dari potongan data secara paralel).

Contoh ini memecah sebuah slice angka menjadi beberapa bagian, menghitung jumlah (sum) untuk setiap bagian secara concurrent, kemudian menggabungkan hasilnya.


Kode: Parallel Sum dengan Goroutine, Channel, dan WaitGroup

package main import ( "fmt" "sync" ) func main() { // Data input: sebuah slice angka. numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} // Tentukan jumlah worker (goroutine) yang akan digunakan. numWorkers := 3 // Hitung ukuran chunk berdasarkan jumlah worker. chunkSize := (len(numbers) + numWorkers - 1) / numWorkers // Channel untuk mengumpulkan partial sum dari tiap worker. results := make(chan int, numWorkers) var wg sync.WaitGroup // Bagi data dan proses secara concurrent. for i := 0; i < len(numbers); i += chunkSize { wg.Add(1) // Tentukan batas akhir chunk. end := i + chunkSize if end > len(numbers) { end = len(numbers) } chunk := numbers[i:end] go func(nums []int) { defer wg.Done() partialSum := 0 for _, n := range nums { partialSum += n } // Kirim hasil partial sum ke channel. results <- partialSum }(chunk) } // Goroutine terpisah untuk menunggu semua worker selesai, lalu menutup channel. go func() { wg.Wait() close(results) }() // Menggabungkan semua partial sum dari channel. totalSum := 0 for sum := range results { totalSum += sum } fmt.Println("Total Sum:", totalSum) }

Penjelasan Mekanisme:

  1. Pembagian Data (Chunking):

    • Data numbers dibagi ke dalam beberapa bagian (chunk) berdasarkan jumlah worker.
    • Misal, dengan 10 angka dan 3 worker, masing-masing worker akan memproses sekitar 4 angka (pembagian dihitung agar semua data tercakup).
  2. Eksekusi Concurrent dengan Goroutine:

    • Untuk setiap chunk, kita memanggil sebuah goroutine untuk menghitung partial sum.
    • Setiap goroutine mengirimkan hasilnya ke channel results.
  3. Sinkronisasi dengan WaitGroup:

    • sync.WaitGroup memastikan bahwa kita menunggu semua goroutine selesai.
    • Setelah semua goroutine selesai (wg.Wait()), channel results ditutup agar loop pembacaan (for range) di main bisa berhenti.
  4. Penggabungan Hasil:

    • Goroutine utama membaca dari channel results dan mengakumulasi semua partial sum menjadi total sum.

Keuntungan Pendekatan Ini:

  • Efisiensi:
    Dengan memecah pekerjaan dan menjalankannya secara concurrent, total waktu komputasi dapat berkurang, terutama jika data besar dan ada banyak core CPU.

  • Sederhana dan Aman:
    Penggunaan channel dan WaitGroup membantu sinkronisasi antar goroutine tanpa memerlukan mekanisme penguncian (mutex) secara manual.

  • Skalabilitas:
    Pendekatan ini dapat dengan mudah disesuaikan dengan jumlah worker yang diinginkan, tergantung pada sumber daya yang tersedia.

Contoh ini merupakan pola yang berguna untuk mempercepat proses komputasi dengan membagi pekerjaan ke beberapa goroutine dan menggabungkan hasilnya secara efisien. Jika ada pertanyaan atau ingin contoh lain, silakan ditanyakan!