场景模拟:
在1000000个1-100的数中,插入一个101,分两种搜索:
1.单核搜索,记录时间
2.多核搜索,记录时间
代码:
package main
import (
"fmt"
"math/rand"
"runtime"
"time"
)
var a []int
var b []int
func main(){
rand.Seed(time.Now().UnixNano())
a = make([]int, 10000000)
for i := 0; i < 9999999; i++ {
a[i] = rand.Intn(100)
}
//fmt.Println(a[0],a[1])
insertIndex := rand.Intn(9999999)
fmt.Printf("101插入的位置是%v\n", insertIndex)
b = make([]int, 10000001)
for i := 0; i < insertIndex; i++ {
b[i] = a[i]
}
b[insertIndex] = 101
for i := insertIndex + 1; i < 10000001; i++ {
b[i] = a[i - 1]
}
//fmt.Println(b[99999])
start := time.Now()
//直接在数组中查找
for i := 0; i < 10000001; i++ {
//fmt.Println(b[i])
if b[i] == 101 {
fmt.Printf("单核模式寻找到了%v个位置为101\n", i)
break
}
}
time.Sleep(time.Second * 1)
t := time.Now()
fmt.Printf("单核模式用时是%v\n", (t.Sub(start)))
fmt.Printf("CPUNUMS = %v\n", runtime.NumCPU())
nlen := 10000000 / runtime.NumCPU()
//多个cpu一起找
//start = time.Now()
index := 1
for i := 0; i < runtime.NumCPU(); i++ {
//fmt.Printf("人呢?\n")
go find(i * nlen, (i + 1) * nlen, index)
index++
}
//time.Sleep(time.Second * 1)
//t = time.Now()
//fmt.Printf("differents = %v\n", (t.Sub(start)))
time.Sleep(time.Second * 2)
}
func find(l, r , index int) {
fmt.Printf("我是协程%v, 现在是%v\n", index, time.Now().UnixNano())
start := time.Now()
time.Sleep(time.Second * 1)
for i := l; i < r; i++ {
if b[i] == 101 {
t := time.Now()
fmt.Printf("我是协程%v, 我找到了101, 在%v个位置, 用了%v时间\n", index, i, (t.Sub(start)))
return
}
}
t := time.Now()
fmt.Printf("我是协程%v, 没找到了101, 用了%v时间\n", index, (t.Sub(start)))
}
结果与分析:
首先插入位置为7893575
其中,每个时间应该都减1秒(加1秒的目的是为了不让结果显示为0)
每个协程遍历2500000个,协程4只用找393575个,是其他协程遍历个数的4/25,是单核遍历个数的4/79
按理来说,协程4时间的6倍为其他协程的时间,协程4的时间的20倍为单核
结论1:多核确实并行,因为执行开始时间相同
结论2:利用多核实现协程确实可以提速
总结:
go关键字可以使用多协程,提高程序运行速度