Skip to content

Instantly share code, notes, and snippets.

@hosszukalman
Last active April 23, 2020 07:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hosszukalman/477382d88d6275deac37c133355c1892 to your computer and use it in GitHub Desktop.
Save hosszukalman/477382d88d6275deac37c133355c1892 to your computer and use it in GitHub Desktop.
Sum() implementations with concurency
09:55 $ go run speedupfor.go
Using sum function: 64416925
39.187µs
Using sumWG function: 64416925
3.486436ms
Using sumChAndWG function: 64416925
33.303102ms
Using sumAtomic function: 64416925
2.848421ms
Using sumSelect function: 64416925
6.064732ms
Using sumCPU function: 64416925
16.621µs
package main
import (
"fmt"
"runtime"
"sync"
"sync/atomic"
"time"
)
const maxNum = 11350
func sum() (res int) {
for i := 0; i <= maxNum; i++ {
res += i
}
return
}
func sumWG() (res int) {
var wg sync.WaitGroup
var mu sync.Mutex
for i := 0; i <= maxNum; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
mu.Lock()
res += i
mu.Unlock()
}(i)
}
wg.Wait()
return
}
func sumChAndWG() (res int) {
sum := make(chan int)
wg := sync.WaitGroup{}
for i := 1; i <= maxNum; i++ {
wg.Add(1)
go func(i int) {
temp := <-sum
temp += i
wg.Done()
sum <- temp
}(i)
}
sum <- 0
wg.Wait()
res = <-sum
close(sum)
return
}
func sumAtomic() (res int32) {
atomicRes := new(int32)
wg := sync.WaitGroup{}
for i := 0; i <= maxNum; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
atomic.AddInt32(atomicRes, int32(i))
}(i)
}
wg.Wait()
return atomic.LoadInt32(atomicRes)
}
func sumSelect() (res int) {
sumCh := make(chan int)
incrementCh := make(chan int)
endCh := make(chan bool)
go func(sumCh, incrementCh chan int, endCh chan bool) {
sum := 0
for {
select {
case i := <-incrementCh:
sum += i
case <-endCh:
sumCh <- sum
}
}
}(sumCh, incrementCh, endCh)
for i := 0; i <= maxNum; i++ {
incrementCh <- i
if i == maxNum {
endCh <- true
}
}
res = <-sumCh
return
}
func sumCPU() (res int) {
n := runtime.NumCPU()
sumCh := make(chan int)
incrementer := maxNum/n
odd := maxNum%n
for i := 1; i <= n; i++ {
go func(i int, sumCh chan int) {
sum := 0
start := (i - 1) * incrementer + odd + 1
if i == 1 {
start = 0
}
end := i * incrementer + odd
for j := start; j <= end; j++ {
sum += j
}
sumCh <- sum
}(i, sumCh)
}
for i := 1; i <= n; i++ {
res += <-sumCh
}
close(sumCh)
return
}
func main() {
start := time.Now()
fmt.Printf("Using sum function: %v\n", sum())
elapsed := time.Since(start)
fmt.Println(elapsed)
start = time.Now()
fmt.Printf("Using sumWG function: %v\n", sumWG())
elapsed = time.Since(start)
fmt.Println(elapsed)
start = time.Now()
fmt.Printf("Using sumChAndWG function: %v\n", sumChAndWG())
elapsed = time.Since(start)
fmt.Println(elapsed)
start = time.Now()
fmt.Printf("Using sumAtomic function: %v\n", sumAtomic())
elapsed = time.Since(start)
fmt.Println(elapsed)
start = time.Now()
fmt.Printf("Using sumSelect function: %v\n", sumSelect())
elapsed = time.Since(start)
fmt.Println(elapsed)
start = time.Now()
fmt.Printf("Using sumCPU function: %v\n", sumCPU())
elapsed = time.Since(start)
fmt.Println(elapsed)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment