开发者学堂课程【Go语言核心编程 - 面向对象、文件、单元测试、反射、TCP编程:协程求素数的代码效率测试】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9761
协程求素数的代码效率测试
即使意义不大,但现在需要证明一个地方,如果我们用 goroutine 和 channel 进行一个并发,现在我们进行的是并行,因为做了四个 cpu,但是到底效率是否有提高呢?大家肯定有所怀疑,因此我们可以使用 goroutine 完成后,可以在使用传统的方法统计一下,看看完成这个任务,各自耗费的时间是多少。大家可以猜测提高了多少倍,例如,四倍,因为使用了四个 cpu,我们可以来证明一下。教大家以后怎么去测。这个是很简单的。
内容介绍
一、测试效率
二、课堂作业
三、channel 使用细节和注意事项
一、 测试效率
代码如下:
Start := time.Now().Unix()
//开启一个协程,,向 intChan 放入1-8000个数
Go putNum(intChan)
讲解:putNum 就算是开始,time.Now().Unix()这个就是关于 Unix 的一个时间簇,我们需要知道怎样这个才算结束,这个就算结束了。在这里,打印跟我们的任务没有关系,理论上说,close 就算是结束了,一旦拿到四个退出,就说明这个任务就是完成了。
//开启四个协程,,从 intChan 取出数据并判断是否为素数,(素数是除了一和它本身能整除,其余不能整除的素数)如果是,就放入到 primeChan
for i := 0; i< 4; i++{
go putNum(intChan, primeChan, exitChan)
}
讲解:接下来,我们再做一个 end 的实践,统计一下我们的效率。代码如下:
End := time.Now().Unix()
Fmt.println(“使用协程耗时=”,end-start)//直接打印出时间
讲解:讲完之后,我们可以让它运行,数字为8000,为了直接看到效果,就将打印先关闭,运行时,数值代为8000,因为打印太耗费时间。因为最主要的部分是
For i :=0; I < 4; i ++{
<- exitChan
}
讲解:此时,我们将代码运行一遍,看看效果。要在打印中吧 res 删除,不需要打印,把其他都保存,时间打出来就好。运行时发现,这个时间太长,所以我们需要换一个数字,换为1000试一试,并将时间延迟关掉,//time . sleep(time . millisecond * 10);再次运行,我们可以发现,数据速度太快,得到下图:
放入8000个数字的时候,耗费了一秒的时间;将8000改为20000,再次运行,看到这个也是很快;再次将数字换为80000,再次运行,
得到下图:
我们可以看到耗时2秒,是正确的,
//当我们从 exitChan 取出4个结果,就可以放心的关闭 primeChan
close(primeChan)
}()
for 1 := 0; 1 <= 8000; 1++{ //循环
intChan<- 1
}
for {
//time . sleep(time . millisecond * 10)
num, ok:=<- intChan
if ! ok { //intChan取不到
break
}
讲解:接下来,我们使用传统的方法做一个测试。先新建一个文件 test.go,再将统计代码粘贴,直接使用 for 循环,
Package main
Import (
“time”
“fmt”
)
Func main() {
讲解:使用外层 for 循环,这里使用 num,如果 num 最后出来,就是一个,一般经过 for 循环,一个数据就出来了,将结果打印出来,将开始的数据放到前面,将耗时的代码也放入,看看花了多少时间,没有协程的普通的方法是放入 Fmt.println(“普通的方法耗时=”,end-start),放入 fmt 包包,理论上这个大概在八秒,不能低于这个。保存看代码,得到下图:
可以看到,这里的时间是10秒,从这里我们可以感受到,使用协程确实是更好一些,
Start := time.Now().Unix()
For num := 1; num <= 80000; num++{
flag := true //假设是素数
//判断 num 是不是素数
for i := 2; I < num;i++ {
if num % 1 == q {//说明该 num 不是素数
flag = false
break//退出 for 循环。退出 for 循环,就取不到东西
}
}
If flag{
//将这个数就放入到 primeChan
//primeChan<-num
}
}
end := time.Now().Unix()
Fmt.println(“普通的方法耗时=”,end-start)//直接打印出时间
二、课堂作业(只有做了,才能会)
在老师讲的基础,同学们对于这些问题会更加熟练,会更加有思路。要求同学们都去做,只有做了,才能学会,只要能理解通,才会。
三、channel 使用细节和注意事项
使用 go 协程后,执行的速度,比普通方法提高至少4倍
讲解:这个还跟 cpu 有关系,大家可以尝试更多可能,将个别数字更改,但其实速度并不会有多大区别,我们可以试运行,发现其实时间变化没有多大改变,协程是作用在4个 cpu 上的,所以不会开更多协程就时间更短,因为 cpu 是定性的,所以很难改变,我们可以看任务管理器,看到 cpu 直接上升的很快,如果 cpu 都利用起来,就说明我们已经用的很好了,