加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
14.8-gofibonacci.go 1.90 KB
一键复制 编辑 原始数据 按行查看 历史
Letotn 提交于 2023-02-11 22:11 . add practice 14.8
package main
import (
"fmt"
"time"
)
// 从示例 6.13 fibonacci.go 的斐波那契程序开始,制定解决方案,使斐波那契周期计算独立到协程中,并可以把结果发送给通道。
// 结束的时候关闭通道。main() 函数读取通道并打印结果:goFibonacci.go
// 使用练习 6.9 fibonacci2.go 中的算法写一个更短的 gofibonacci2.go
// 使用 select 语句来写,并让通道退出 (gofibonacci_select.go)
// 注意:当给结果计时并和 6.13 对比时,我们发现使用通道通信的性能开销有轻微削减;这个例子中的算法使用协程并非性能最好的选择;
// 但是 gofibonacci3 方案使用了 2 个协程带来了 3 倍的提速。
var list = []uint64{1, 1}
func gofibo1(n int) chan uint64 {
res := make(chan uint64)
go func() {
if n <= 0 {
res <- 1
} else if len(list) > n {
res <- list[n]
} else {
n1 := <-gofibo1(n - 1)
n2 := <-gofibo1(n - 2)
val := n1 + n2
res <- val
list = append(list, val)
}
close(res)
}()
return res
}
func gofibo2(n int, ch chan uint64) {
x, y := uint64(1), uint64(1)
for i := 0; i < n; i++ {
ch <- x
x, y = y, x+y
}
close(ch)
}
func gofibo3(ch chan uint64, quit chan bool) {
x, y := uint64(1), uint64(1)
for {
select {
case ch <- x:
x, y = y, x+y
case <-quit:
return
}
}
}
func main() {
n := 20
ts := time.Now().UnixMicro()
for i := 0; i < n; i++ {
fmt.Println(<-gofibo1(i))
}
td := time.Now().UnixMicro()
fmt.Println("cost time: ", td-ts)
c := make(chan uint64, n)
go gofibo2(n, c)
for i := 0; i < n; i++ {
fmt.Println(<-c)
}
tc := time.Now().UnixMicro()
fmt.Println("cost time: ", tc-td)
// 使用select方法
ch := make(chan uint64)
quit := make(chan bool)
go gofibo3(ch, quit)
for i := 0; i < n; i++ {
fmt.Println(<-ch)
}
// 接收完N个数之后中断协程
quit <- true
fmt.Println("cost time: ", time.Now().UnixMicro()-tc)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化