Last active
September 3, 2022 09:56
-
-
Save ysinjab/8e94b44aaca321b150f2d5f57cb7a75c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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