When we hear the term goroutines the very first thing that come to our mind is, it’s way faster than threads, pretty much lightweight as compared to threads and is managed by the Go runtime which doesn’t depend much on the Operating System.

Many of those who had freshly started with Go will be in an assumption that any sequence of actions can be parallelizable by spinning multiple go-routines. But that’s true only to a certain extent and increasing more go-routines doesn’t help after that.

So without much lag, let’s get straight on to the point. In this blog post, I will try to convey some top-level observations on how goroutines work.

As this is intended to be understood for people who have minimal to zero knowledge in Go, I will be taking an example of computing Fibonacci Sequence for 1–40 numbers and return a map with key as number and value as the Fibonacci value of the key.


Base Level Calculation without any parallelism

type compute struct {
		sync.RWMutex
		response map[int]int
	}

	func fib(i int) int {
		if i == 0 {
			return 0
		}
		if i == 1 {
			return 1
		}
		return fib(i-1) + fib(i-2)
	}

	func (c *compute) sequentialFibonacci(count int) {
		for i := 0; i < count; i++ {
			c.response[i] = fib(i)
		}
	}
	func main() {
		runtime.GOMAXPROCS(4)
		action := flag.String("action", "sequential", "Specify if fib had to be sequentially computed or parallel")
		flag.Parse()
		startTime := time.Now()
		c := compute{response: make(map[int]int, 40)}
		switch *action {
		case "sequential":
			c.sequentialFibonacci(40)
		case "parallel":
	    panic("not yet implemented")
		}
		fmt.Println("Total time taken ", time.Since(startTime).Milliseconds())
	}

So here we have a flag which asks if the client had to do sequential processing or parallel processing. Considering only sequential is implemented, we are iterating from 0–30 using a for loop and on every iteration, we are computing the Fibonacci of that particular iteration key and storing it into a map.

If you look at the above code, when I was computing for Fibonacci of 1, all the other 39 computations are waiting for the first one to get done.

Similarly, on Fibonacci of 2, the remaining 38 keeps waiting which means our sequential processing is increasing the wait time of the client.

Image for post

As you can see in the above screenshot it’s taking 990 ms on an average to compute the Fibonacci sequence of first 40 numbers. Let’s try parallelising the task with the help of Goroutines and see how it scales.

#parallel-computing #go #goroutines

Go: Common Misconceptions About Goroutines
1.30 GEEK