普通的pipeline stage代碼
package main
import (
"math/rand"
"time"
"fmt"
)
func main() {
rands := func() interface{} {return rand.Intn(500000000)}
toInt := func(done <-chan interface{},
value <-chan interface{}) <-chan int {
randInt := make(chan int)
go func() {
defer close(randInt)
for v := range value {
select {
case <-done:
return
case randInt <- v.(int):
}
}
}()
return randInt
}
repeatRand:= func(done <-chan interface{},
fn func() interface{} ) <-chan interface{} {
intData := make(chan interface{})
go func() {
defer close(intData)
for {
select {
case <-done:
fmt.Println("111Goroutine 退出")
return
case intData<- fn():
}
}
}()
return intData
}
Take := func(done <-chan interface{},
valueStream <-chan interface{},
num int) <-chan interface{}{
takeStream := make(chan interface{})
go func() {
defer fmt.Println("222Goroutine 退出")
defer close(takeStream)
for i := 0; i < num; i++ {
select {
case <-done:
return
case takeStream <-<-valueStream:
}
}
}()
return takeStream
}
panduan := func(n int) bool {
for i:=2;i<n;i++ {
if n % i == 0 {
return false
}
}
return true
}
primeFinder := func(done <-chan interface{},
value <-chan int) <-chan interface{} {
primesTREAM := make(chan interface{})
go func() {
for v := range value {
if panduan(v) {
select {
case <-done:
return
case primesTREAM<- v:
}
}else {
continue
}
}
}()
return primesTREAM
}
done := make(chan interface{})
start := time.Now()
randIntStream := toInt(done,repeatRand(done,rands))
fmt.Println("Primes: ")
for prime := range Take(done,primeFinder(done,randIntStream),10) {
fmt.Println(prime)
}
close(done)
fmt.Printf("Search took:%v ",time.Since(start))
}
扇入扇出代碼
package main
import (
"math/rand"
"time"
"fmt"
"runtime"
"sync"
)
func main() {
rands := func() interface{} {return rand.Intn(500000000)}
toInt := func(done <-chan interface{},
value <-chan interface{}) <-chan int {
randInt := make(chan int)
go func() {
defer close(randInt)
for v := range value {
select {
case <-done:
return
case randInt <- v.(int):
}
}
}()
return randInt
}
repeatRand:= func(done <-chan interface{},
fn func() interface{} ) <-chan interface{} {
intData := make(chan interface{})
go func() {
defer close(intData)
for {
select {
case <-done:
fmt.Println("111Goroutine 退出")
return
case intData<- fn():
}
}
}()
return intData
}
Take := func(done <-chan interface{},
valueStream <-chan interface{},
num int) <-chan interface{}{
takeStream := make(chan interface{})
go func() {
defer fmt.Println("222Goroutine 退出")
defer close(takeStream)
for i := 0; i < num; i++ {
select {
case <-done:
return
case takeStream <-<-valueStream:
}
}
}()
return takeStream
}
panduan := func(n int) bool {
for i:=2;i<n;i++ {
if n % i == 0 {
return false
}
}
return true
}
primeFinder := func(done <-chan interface{},
value <-chan int) <-chan interface{} {
primesTREAM := make(chan interface{})
go func() {
for v := range value {
if panduan(v) {
select {
case <-done:
return
case primesTREAM<- v:
}
}else {
continue
}
}
}()
return primesTREAM
}
fanIn := func(done <- chan interface{},
channels ...<-chan interface{}) <-chan interface{} {
var wg sync.WaitGroup
multiPlexedStream := make(chan interface{})
mutiplex := func(c <-chan interface{}) {
defer wg.Done()
for i:= range c {
select {
case <-done:
return
case multiPlexedStream<-i:
}
}
}
wg.Add(len(channels))
for _,c := range channels {
go mutiplex(c)
}
go func() {
wg.Wait()
close(multiPlexedStream)
}()
return multiPlexedStream
}
done := make(chan interface{})
start := time.Now()
randIntStream := toInt(done,repeatRand(done,rands))
// fmt.Println("Primes: ")
// for prime := range Take(done,primeFinder(done,randIntStream),10) {
// fmt.Println(prime)
// }
numinders := runtime.NumCPU()
fmt.Printf("Spanning up %d prime finders", numinders)
finders := make([]<-chan interface{},numinders)
fmt.Println("Primes: ")
for i := 0; i < numinders; i++ {
finders[i] = primeFinder(done,randIntStream)
}
for prime := range Take(done,fanIn(done,finders...),10){
fmt.Printf("\t%v\n",prime)
}
close(done)
fmt.Printf("Search took:%v ",time.Since(start))
}
性能對比
普通:
24s左右
扇入扇出
12s左右
性能提升了50%.