多线程归并排序 go实现

特性

  • 线程数可以调整
  • 混合使用归并排序的递归版和非递归版实现减少递归调用损耗
  • 线程利用率高
  • 不足:归并排序的merge部分,任务无法分摊,没有充分利用

1000万的随机数

  • 递归版时间

    real    0m3.037s
    user    0m2.859s
    sys     0m0.125s
    
  • 单线程

      BenchmarkT1-4             10    2718827530 ns/op    268435456 B/op         2 allocs/op
    
  • 双线程

      BenchmarkT2-4             10    1783577760 ns/op    268435792 B/op         4 allocs/op
    
  • 四线程

      BenchmarkT4-4             10    1692288480 ns/op    268436278 B/op         7 allocs/op
    

代码

package main

func merge(x, y, out []int) {
    n, m := len(x), len(y)
    for i, j, k := 0, 0, 0; k < n+m; k++ {
        if i < n && j < m {
            if x[i] < y[j] {
                out[k] = x[i]
                i++
            } else {
                out[k] = y[j]
                j++
            }
        } else {
            if i < n {
                out[k] = x[i]
                i++
            } else {
                out[k] = y[j]
                j++
            }
        }
    }
}
func min(x, y int) int {
    if x < y {
        return x
    }
    return y
}
func mergesortT(arr, buff []int) {
    n := len(arr)
    x, y := arr, buff
    i, j, k := 0, 0, 0
    for i = 1; i < n; i <<= 1 {
        for j = 0; j < n-i; j = k {
            k = min(n, j+2*i)
            merge(x[j:j+i], x[j+i:k], y[j:k])
        }
        x, y = y, x
    }
    if &x[0] != &arr[0] {
        copy(arr, x)
    }
}
func mergesort(arr, buff []int, sed chan int, level int) {
    n := len(arr)
    if n <= 2 || level <= 1 {
        mergesortT(arr, buff)
        if sed != nil {
            sed <- 0
        }
        return
    }
    recv := make(chan int)
    mid := n >> 1
    go mergesort(arr[:mid], buff[0:mid], recv, level>>1)
    mergesort(arr[mid:], buff[mid:], nil, level>>1)
    <-recv
    merge(arr[:mid], arr[mid:], buff)
    copy(arr, buff)
    if sed != nil {
        sed <- 0
    }
}

func MergeSort(arr []int, t int) {
    buff := make([]int, len(arr))
    mergesort(arr, buff, nil, t)
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文有七千字,阅读大约需要占用你10分钟时间。 好吧。。随便写的,我也不知道会花多久看完。因为写的比较烂,而且只是...
    锅与盆阅读 8,193评论 5 36
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,747评论 0 15
  • 这里用金刚狼和蝙蝠侠代表两位魔术师 不要揭穿魔术有一个桥段:小男孩看穿了把小鸟变走的把戏,小鸟没有消失,而是被压扁...
    开心短毛阅读 448评论 0 0
  • 如果提前了解了你所要面对的人生,你是否还会有勇气前来? 人生应该怎么度过,值得怎么度过?看过电影《无问西东》后我开...
    羊耶买买提阅读 258评论 0 3
  • 此刻,我回到了鹏城,仿佛做了一个长长的梦,现在梦醒了,可是我还在贪睡。 在火车上的时候,在追一部剧《THIS IS...
    知鱼君阅读 134评论 0 0