Skip to content

Instantly share code, notes, and snippets.

@ysinjab
Last active September 3, 2022 09:56
Show Gist options
  • Save ysinjab/8e94b44aaca321b150f2d5f57cb7a75c to your computer and use it in GitHub Desktop.
Save ysinjab/8e94b44aaca321b150f2d5f57cb7a75c to your computer and use it in GitHub Desktop.
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}
func main() {
// fibCalculator will calculate fibonacci number for a stream of numbers
fibCalculator := func(done <-chan interface{}, numbers <-chan int) <-chan interface{} {
fibStream := make(chan interface{})
go func() {
defer close(fibStream)
for i := range numbers {
f := fibonacci(i)
select {
case fibStream <- f:
case <-done:
return
}
}
}()
return fibStream
}
fanIn := func(
done <-chan interface{},
channels ...<-chan interface{},
) <-chan interface{} {
var wg sync.WaitGroup
multiplexedStream := make(chan interface{})
multiplex := func(c <-chan interface{}) {
defer wg.Done()
for i := range c {
select {
case <-done:
return
case multiplexedStream <- i:
}
}
}
// Select from all the channels
wg.Add(len(channels))
for _, c := range channels {
go multiplex(c)
}
// Wait for all the reads to complete
go func() {
wg.Wait()
close(multiplexedStream)
}()
return multiplexedStream
}
done := make(chan interface{})
randomNumbersStream := make(chan int)
go func(
done <-chan interface{},
numbers chan int) {
for {
r := rand.Intn(50)
select {
case numbers <- r:
case <-done:
return
}
}
}(done, randomNumbersStream)
calculators := make([]<-chan interface{}, runtime.NumCPU())
for i := 0; i < runtime.NumCPU(); i++ {
calculators[i] = fibCalculator(done, randomNumbersStream)
}
go func() {
fmt.Println("let's see how many fabonacci can the Fan-in Fan-out calculate in 10 seconds")
time.Sleep(10 * time.Second)
close(done)
close(randomNumbersStream)
}()
start := time.Now()
i := 0
for fab := range fanIn(done, calculators...) {
fmt.Println(fmt.Sprintf("calculated the following fab: %d at iteration %d", fab, i))
i++
}
fmt.Printf("calculation took: %v", time.Since(start))
// When running it on my 8 cpu cores: it calculated 40 numbers in 19 seconds
// When I run one calculator it calculated 2 numbers in 40 seconds
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment