Search code examples
gogoroutine

Why is my code running slower after trying Goroutines?


I decided to try figuring out Goroutines and channels. I made a function that takes a list and adds 10 to every element. I then made another function that attempts to incorporate channels and goroutines. When I timed the code it ran much slower. I tried doing some research but was unable to figure anything out.

Here is my code with channels:

package main

import ("fmt"
        "time")

func addTen(channel chan int) {
    channel <- 10 + <-channel
}

func listPlusTen(list []int) []int {
    channel := make(chan int)
    for i:= 0; i < len(list); i++ {
        go addTen(channel)
        channel <- list[i]
        list[i] = <-channel
    }
    return list
}

func main(){
    var size int
    list := make([]int, 0)
    fmt.Print("Enter the list size: ")
    fmt.Scanf("%d", &size)

    for i:=0; i <= size; i++ {
        list = append(list, i)
    }
    start := time.Now()
    list = listPlusTen(list)
    end := time.Now()
    fmt.Println(end.Sub(start)) 
}

Solution

  • You are adding a lot of synchronization overhead to the baseline algorithm. You have len(list) goroutines, all waiting to read from a common channel. When you write to the channel, the scheduler picks one of those goroutines, and that goroutines adds 10, and writes to the channel, which enables the main goroutine again. It is hard to speculate without really measuring it, but if you move the goroutine creation outside the for-loop, then you will have only one goroutine, reducing the scheduler overhead. However, in any comparison to the baseline algorithm this will be slower, because each operation involves two synchronizations and two context switches, which take more that the algorithm itself.