上代码,写了个速度比较程序来熟悉熟悉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要快。另一个没想到并行版本比配普通版本要慢。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注