go语言归并排序和快排速度的测试
上代码,写了个速度比较程序来熟悉熟悉golang
package main
import "fmt"
import "math/rand"
import "sort"
import "time"
import "reflect"
import "runtime"
func merge(nums []int, mid int){
//fmt.Println("merge been called")
//print_slice(nums)
length := len(nums)
p1 := 0
p2 := mid
p := 0
tmp := make([]int,length)
for p1<mid&&p2<length {
if nums[p1]<nums[p2] {
tmp[p] = nums[p1]
p1++
p++
}else {
tmp[p] = nums[p2]
p2++
p++
}
}
for p1<mid {
tmp[p] = nums[p1]
p1++
p++
}
for p2<length {
tmp[p] = nums[p2]
p2++
p++
}
//fmt.Printf("p=%v p1=%v p2=%v mid=%v length=%v\n",p,p1,p2,mid,length)
//fmt.Print("nums:")
//print_slice(nums)
//fmt.Print("tmp:")
//print_slice(tmp)
copy(nums,tmp)
//fmt.Println("merge done")
}
func merge_sort_normal(nums []int){
length := len(nums)
if length==1 {
return
}
mid := length/2
merge_sort_normal(nums[:mid])
merge_sort_normal(nums[mid:])
merge(nums,mid)
}
func print_slice(nums []int){
fmt.Print("[")
for _,x:=range nums {
fmt.Printf("%v ",x)
}
fmt.Printf("] len=%v cap=%v\n",len(nums),cap(nums))
}
func merge_sort_parallel_recursion(nums []int,c chan bool){
//print_slice(nums)
length := len(nums)
if length==1 {
c<-true
return
}
mid := length/2
nc := make(chan bool)
go merge_sort_parallel_recursion(nums[:mid],nc)
go merge_sort_parallel_recursion(nums[mid:],nc)
<-nc
<-nc
merge(nums,mid)
c<-true
}
func merge_sort_parallel(nums []int){
c := make(chan bool)
go merge_sort_parallel_recursion(nums,c)
<-c
}
func quick_sort_normal(nums []int){
length := len(nums)
if length<=1 {
return
}
//fmt.Println("enter")
//print_slice(nums)
val := nums[0]
p1 := 0
p2 := length-1
t := 0
for p1<=p2 {
for ;p1<=p2;p2-- {
if nums[p2]<val {
break
}
}
if p1<=p2 {
nums[p1] = nums[p2]
t = p2
//p1++
}
for ;p1<=p2;p1++ {
if nums[p1]>val {
break
}
}
if p1<=p2 {
nums[p2] = nums[p1]
t = p1
//p2--
}
}
nums[t] = val
//print_slice(nums)
//fmt.Printf("p1=%v p2=%v\n",p1,p2)
quick_sort_normal(nums[:t])
quick_sort_normal(nums[t+1:])
//fmt.Println("done")
}
func quick_sort_parallel_recursion(nums []int, c chan bool){
//print_slice(nums)
length := len(nums)
if length<=1 {
c<-true
return
}
val := nums[0]
p1 := 0
p2 := length-1
t := 0
for p1<=p2 {
for ;p1<=p2;p2-- {
if nums[p2]<val {
break
}
}
if p2>=p1 {
//fmt.Printf("nums[%v] = nums[%v]\n",p1,p2)
nums[p1] = nums[p2]
t = p2
//p1++
}
for ;p1<=p2;p1++ {
if nums[p1]>val {
break
}
}
if p1<=p2 {
//fmt.Printf("nums[%v] = nums[%v]\n",p2,p1)
nums[p2] = nums[p1]
t = p1
//p2--
}
}
nums[t] = val
nc := make(chan bool)
go quick_sort_parallel_recursion(nums[:t],nc)
go quick_sort_parallel_recursion(nums[t+1:],nc)
/*
if p2>=0{
go quick_sort_parallel_recursion(nums[:p2],nc)
}else{
go quick_sort_parallel_recursion([]int{},nc)
}
if p2+1<length{
go quick_sort_parallel_recursion(nums[p2+1:],nc)
}else{
go quick_sort_parallel_recursion([]int{},nc)
}
*/
<-nc
<-nc
c<-true
}
func quick_sort_parallel(nums []int){
c := make(chan bool)
go quick_sort_parallel_recursion(nums,c)
<-c
}
func main(){
num := 1000000
v := make([]int, num)
for i:=0;i<num;i++ {
v[i] = rand.Intn(num)
}
baseline := make([]int,num)
copy(baseline,v)
sort.Ints(baseline)
funcs := []func([]int){sort.Ints,merge_sort_normal,merge_sort_parallel,quick_sort_normal,quick_sort_parallel}
for i,f := range funcs{
tmp := make([]int,num)
copy(tmp,v)
start_time := time.Now()
f(tmp)
time_elapsed := time.Since(start_time)
correct := true
for j:=0;j<num;j++{
if baseline[j]!=tmp[j]{
correct = false
break
}
}
name := runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
fmt.Printf("%v\t%-50v%15v\t%v\n",i,name,time_elapsed,correct)
}
}
在我电脑上的运行结果为
0 sort.Ints 155.7437ms true
1 main.merge_sort_normal 117.5517ms true
2 main.merge_sort_parallel 419.6172ms true
3 main.quick_sort_normal 73.3922ms true
4 main.quick_sort_parallel 120.0331ms true
还是挺出乎我意料的,一个是没想到快排可以做到比内置的sort.Ints要快。另一个没想到并行版本比配普通版本要慢。