利用并发方法更快地计算斐波纳契数
package main
import (
"fmt"
"math/rand"
"time"
)
func fib(number float64) float64 {
x, y := 1.0, 1.0
for i := 0; i < int(number); i++ {
x, y = y, x+y
}
r := rand.Intn(3)
time.Sleep(time.Duration(r) * time.Second)
return x
}
func main() {
start := time.Now()
for i := 1; i < 15; i++ {
n := fib(float64(i))
fmt.Printf("Fib(%v): %v\n", i, n)
}
elapsed := time.Since(start)
fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}
1
1
2
3
5
8
13
quit
Done calculating Fibonacci!
Done! It took 12.043196415 seconds!
实现并发并使程序的运行速度更快的改进版本如下所示:
package main
import (
"fmt"
"math/rand"
"time"
)
func fib(number float64, ch chan string) {
x, y := 1.0, 1.0
for i := 0; i < int(number); i++ {
x, y = y, x+y
}
r := rand.Intn(3)
time.Sleep(time.Duration(r) * time.Second)
ch <- fmt.Sprintf("Fib(%v): %v\n", number, x)
}
func main() {
start := time.Now()
size := 15
ch := make(chan string, size)
for i := 0; i < size; i++ {
go fib(float64(i), ch)
}
for i := 0; i < size; i++ {
fmt.Printf(<-ch)
}
elapsed := time.Since(start)
fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}
输出:
Fib(14): 610
Fib(8): 34
Fib(1): 1
Fib(5): 8
Fib(0): 1
Fib(12): 233
Fib(2): 2
Fib(13): 377
Fib(6): 13
Fib(7): 21
Fib(4): 5
Fib(3): 3
Fib(10): 89
Fib(9): 55
Fib(11): 144
Done! It took 2 seconds!
使用两个无缓冲channel的程序的第二个版本如下所示:
package main
import (
"fmt"
"time"
)
var quit = make(chan bool)
func fib(c chan int) {
x, y := 1, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("Done calculating Fibonacci!")
return
}
}
}
func main() {
start := time.Now()
command := ""
data := make(chan int)
go fib(data)
for {
num := <-data
fmt.Println(num)
fmt.Scanf("%s", &command)
if num > 10000 {
quit <- true
break
}
}
time.Sleep(1 * time.Second)
elapsed := time.Since(start)
fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}
输出:
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
Done calculating Fibonacci!
Done! It took 1 seconds!