Go – simple examples

The video in the previous post, showed how to use channels and start goroutines to turn a sequential task into a concurrent task.

A brief aside for those that are curious: some performance benchmarks can be found here. The go compiler has two different compiler implementations, one of which is gccgo which benefits from using the underlying gcc compiler toolchain, and gcc compiler optimization passes. This is also the version that can compile on solaris (if anyone still uses it). Go code compiled under gccgo may be faster than that which is compiled under the regular Go compiler.

An interesting and simple example was mentioned in the video, and can be found here in the go-play area:

// A concurrent prime sieve

package main

// Send the sequence 2, 3, 4, ... to channel 'ch'.
func Generate(ch chan<- int) {
    for i := 2; ; i++ {
        ch <- i // Send 'i' to channel 'ch'.
    }
}

// Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'.
func Filter(in <-chan int, out chan<- int, prime int) {
    for {
        i := <-in // Receive value from 'in'.
        if i%prime != 0 {
            out <- i // Send 'i' to 'out'.
        }
    }
}

// The prime sieve: Daisy-chain Filter processes.
func main() {
    ch := make(chan int) // Create a new channel.
    go Generate(ch)      // Launch Generate goroutine.
    for i := 0; i < 10; i++ {
        prime := <-ch
        print(prime, "\n")
        ch1 := make(chan int)
        go Filter(ch, ch1, prime)
        ch = ch1
    }
}

And generating the fibonacci sequence on the go-play site:

package main

func fib() func() int {
    a, b := 0, 1
    return func() int {
        a, b = b, a+b
        return b
    }
}

func main() {
    f := fib()
    //  evaluated left to right
    println(f(), f(), f(), f(), f())
}