100-go-mistakes/08-concurrency-foundations/56-faster/main.go
2021-12-27 15:57:20 +01:00

89 lines
1.4 KiB
Go

package main
import "sync"
func sequentialMergesort(s []int) {
if len(s) > 1 {
middle := len(s) / 2
sequentialMergesort(s[:middle])
sequentialMergesort(s[middle:])
merge(s, middle)
}
}
func parallelMergesortV1(s []int) {
if len(s) > 1 {
middle := len(s) / 2
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
parallelMergesortV1(s[:middle])
}()
go func() {
defer wg.Done()
parallelMergesortV1(s[middle:])
}()
wg.Wait()
merge(s, middle)
}
}
const max = 2048
func parallelMergesortV2(s []int) {
if len(s) > 1 {
if len(s) <= max {
sequentialMergesort(s)
} else {
middle := len(s) / 2
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
parallelMergesortV2(s[:middle])
}()
go func() {
defer wg.Done()
parallelMergesortV2(s[middle:])
}()
wg.Wait()
merge(s, middle)
}
}
}
func merge(s []int, middle int) {
helper := make([]int, len(s))
copy(helper, s)
helperLeft := 0
helperRight := middle
current := 0
high := len(s) - 1
for helperLeft <= middle-1 && helperRight <= high {
if helper[helperLeft] <= helper[helperRight] {
s[current] = helper[helperLeft]
helperLeft++
} else {
s[current] = helper[helperRight]
helperRight++
}
current++
}
for helperLeft <= middle-1 {
s[current] = helper[helperLeft]
current++
helperLeft++
}
}