归并排序是典型的分治算法,它不断地将某个数组分为两个部分,分别对左子数组与右子数组进行排序,然后将两个数组合并为新的有序数组。
一般来说,小文件单机版排序比并发排序更快一些,但是大文件无法一次性读入内存处理,需要分块处理。单机版排序无法做到分布式排序,分布式排序需要联网进行,网络传输跟通道传输非常类似,稍作修改就可以做到在网络上进行排序。
并行和并发是有区别的,依赖操作系统和硬件是否支持。同时,在允许的情况下,使用有缓冲的通道和使用文件读写缓冲,有利于加快程序的处理速度,避免及时阻塞。
数组排序
对一个整数数组进行排序,系统库中已经提供了排序函数,直接使用即可。需要注意的是,Go中使用通道,使用不当会造成死锁。需要注意通道的使用,否则一运行就发生竞争条件造成程序无法执行而终止。
// 按升序排序
func InMemSort(in <-chan int) <-chan int {
out := make(chan int, 4096)
// 启动一个协程输出排序数据
go func() {
var a []int
for v := range in {
a = append(a, v)
}
fmt.Println("Read done: ", time.Now().Sub(startTime))
sort.Ints(a)
fmt.Println("Sort done: ", time.Now().Sub(startTime))
// 将排序好的数据输出至通道中
for _, n := range a {
out <- n
}
close(out)
}()
return out
}
通常来说,协程的使用是成对出现的,并且习惯用Go匿名函数来操作。需要留意匿名函数的传参问题,可以去官方文档进行查看。go程运行时,函数调用是瞬间返回的。如果在其它地方使用range操作来处理通道,在通道数据发送完毕时必须显示关闭通道,否则必是死锁错误。