# go 协程实现快排
突发奇想想要用协程优化快排,毕竟他就是分块操作的
| |
| package quicksort |
| |
| type v1 struct{} |
| |
| func QuickSortV1(list []int) []int { |
| if len(list) <= 1 { |
| return list |
| } |
| |
| v1{}.quicksort(list, 0, len(list)-1) |
| return list |
| } |
| |
| func (v v1) quicksort(list []int, low, high int) { |
| if low >= high { |
| return |
| } |
| |
| p := v.partion(list, low, high) |
| |
| v.quicksort(list, low, p-1) |
| v.quicksort(list, p+1, high) |
| } |
| |
| func (v1) partion(list []int, low, high int) int { |
| p := list[low] |
| |
| |
| for low < high { |
| |
| |
| for low < high && p <= list[high] { |
| high-- |
| } |
| list[low] = list[high] |
| |
| |
| |
| for low < high && p >= list[low] { |
| low++ |
| } |
| list[high] = list[low] |
| |
| } |
| |
| |
| list[low] = p |
| |
| |
| return low |
| } |
| |
| package quicksort |
| |
| import ( |
| "fmt" |
| "math/rand" |
| "testing" |
| ) |
| |
| func TestQuickSortV1(t *testing.T) { |
| list := []int{6, 5, 7, 9, 8, 3, 4} |
| |
| |
| list = QuickSortV1(list) |
| fmt.Println(list) |
| } |
| |
| func BenchmarkQuickSortV1(b *testing.B) { |
| |
| |
| list := make([]int, 0, 1000) |
| for i := 0; i < 1000; i++ { |
| list = append(list, rand.Intn(10000)) |
| } |
| for i := 0; i < b.N; i++ { |
| list = QuickSortV1(list) |
| } |
| } |
| |
| package quicksort |
| |
| import "sync" |
| |
| type v2 struct { |
| } |
| |
| func QuickSortV2(list []int) []int { |
| if len(list) <= 1 { |
| return list |
| } |
| v := v2{} |
| v.quicksort(list) |
| return list |
| } |
| |
| func (v v2) quicksort(list []int) { |
| |
| low := 0 |
| high := len(list) - 1 |
| |
| if low >= high { |
| return |
| } |
| |
| p := v.partion(list) |
| |
| var wg sync.WaitGroup |
| |
| wg.Add(2) |
| go func() { |
| defer wg.Done() |
| v.quicksort(list[:p]) |
| }() |
| |
| go func() { |
| defer wg.Done() |
| v.quicksort(list[p+1:]) |
| }() |
| |
| wg.Wait() |
| } |
| |
| func (v v2) partion(list []int) int { |
| low := 0 |
| high := len(list) - 1 |
| |
| p := list[low] |
| |
| |
| |
| for low < high { |
| |
| |
| for low < high && p <= list[high] { |
| high-- |
| } |
| list[low] = list[high] |
| |
| |
| |
| for low < high && p >= list[low] { |
| low++ |
| } |
| list[high] = list[low] |
| |
| } |
| |
| |
| list[low] = p |
| |
| |
| return low |
| } |
| |
| package quicksort |
| |
| import ( |
| "fmt" |
| "math/rand" |
| "testing" |
| ) |
| |
| func TestQuickSortV2(t *testing.T) { |
| |
| |
| |
| |
| |
| list := make([]int, 0, 1000) |
| for i := 0; i < 1000; i++ { |
| list = append(list, rand.Intn(10000)) |
| } |
| list = QuickSortV2(list) |
| fmt.Println(list) |
| } |
| |
| func BenchmarkQuickSortV2(b *testing.B) { |
| list := make([]int, 0, 1000) |
| for i := 0; i < 1000; i++ { |
| list = append(list, rand.Intn(10000)) |
| } |
| for i := 0; i < b.N; i++ { |
| list = QuickSortV2(list) |
| } |
| } |
| go test -bench |
| |
| goos: linux |
| goarch: amd64 |
| pkg: twelveeee.top/leetcode/v2/quickSort |
| cpu: Intel(R) N100 |
| BenchmarkQuickSortV1-4 3266 348109 ns/op |
| BenchmarkQuickSortV2-4 913 1342829 ns/op |
| PASS |
使用了协程之后,性能更差了,估计是频繁请求临界区导致的