Last active
April 20, 2021 10:15
-
-
Save rapando/eb8676172a52c6d3669c62c0947dafbc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"sync" | |
"time" | |
) | |
func main() { | |
// task - multiply each number by 2 then print out the results | |
var msisdns = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} | |
log.Printf("msisdns : %v\n", msisdns) | |
start := time.Now() | |
implementation1(msisdns) | |
log.Printf("Implementation 1 took %v", time.Since(start)) | |
start2 := time.Now() | |
implementation2(msisdns) | |
log.Printf("Implementation 2 took %v", time.Since(start2)) | |
start3 := time.Now() | |
implementation3(msisdns) | |
log.Printf("Implementation 3 took %v", time.Since(start3)) | |
} | |
func implementation1(msisdns []int) { | |
// create 10 goroutines to work on each number | |
log.Printf("Implementation One :: using goroutines and channels") | |
var stopChan = make(chan int, len(msisdns)) | |
for _, msisdn := range msisdns { | |
go multiplyByTwoImplementation1(msisdn, stopChan) | |
} | |
var answer int | |
// the point is to loop 10 times | |
for _ = range msisdns { | |
answer = <-stopChan | |
log.Println("The answer is", answer) | |
} | |
} | |
func multiplyByTwoImplementation1(msisdn int, stopChan chan<- int) { | |
answer := multiplyBy2(msisdn) | |
stopChan <- answer | |
} | |
func implementation2(msisdns []int) { | |
// this one uses waitgroups | |
log.Println("\n\nImplementation 2 : waitgroups") | |
var wg sync.WaitGroup | |
for _, msisdn := range msisdns { | |
wg.Add(1) | |
go multiplyByTwoImplementation2(&wg, msisdn) | |
} | |
wg.Wait() | |
} | |
func multiplyByTwoImplementation2(wg *sync.WaitGroup, msisdn int) { | |
defer wg.Done() | |
answer := multiplyBy2(msisdn) | |
log.Printf("%d * 2 = %d\n", msisdn, answer) | |
} | |
func implementation3(msisdns []int) { | |
log.Println("\n\nImplementation 3 : Using worker pools") | |
// 1. Create the channels: jobs and results. the size of each should be how | |
// many data components you have | |
size := len(msisdns) | |
var jobs = make(chan int, size) | |
var results = make(chan int, size) | |
// 2. Read from the array of data into the jobs channel | |
for _, msisdn := range msisdns { | |
jobs <- msisdn | |
} | |
// 3. Create goroutines and provide them with the jobs and results channels | |
// Note that steps 2 and 3 can be interchanged but it makes sense writing | |
// them in this order | |
noOfGoroutines := 10 // 0 < noOfGoroutines <= size | |
for i := 0; i < noOfGoroutines; i++ { | |
go multiplyByTwoImplementation3(i, jobs, results) | |
} | |
// 4. Read the results (like in implementation 1) | |
var answer int | |
for i := 0; i < len(msisdns); i++ { | |
answer = <-results | |
log.Println("The answer is", answer) | |
} | |
} | |
// we are reading from jobs hence { jobs [<- chan int] } | |
// we are writing to results hence { results [chan <- int] } | |
func multiplyByTwoImplementation3(i int, jobs <-chan int, results chan<- int) { | |
for j := range jobs { | |
answer := multiplyBy2(j) | |
log.Printf("Worker [%d] working on %d", i, j) | |
results <- answer | |
} | |
} | |
func multiplyBy2(i int) int { | |
time.Sleep(time.Second * 2) | |
return i * 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment