The code used in the experiments that follow is pretty simple
- the main module handles the command line arguments and prints the results
- the input module parses the input file and starts a calculation for each input
- the calculation module finds a solution for a single input and writes it to a result channel
My first impressions were mostly positive:
- decent documentation covering the language proper as well as the standard library
- a fast compiler resulting in short edit-compile-test cycles
- a nice standard library and a wealth of packages (provided by the community)
- a lively and friendly mailing list and
The language has quite a “direct” feel to it: I could get to work and be productive almost immediately.
This is in stark contrast to other languages I tried to learn recently e.g. Scala (back in January): it required a lot of reading and even a couple of days into it I was not really productive in Scala.
Go is quite the opposite, the barrier to entry is low, the language is clean and simple. The combined declaration and initialisation operator (
':=') alone is a godsend.
Coming from a Python background the main thing I was missing was the REPL. Who knows, maybe there is even one out there but I just did not find it yet..?
playing with goroutines
One of the most attractive
golang features is its support for concurrent programming via goroutines and I wanted to play with these.
The programming problem chosen came with an input for 50 calculations. I used it to create inputs with 50, 100 and 200 *thousand* calculations. All calculations are independent of each other i.e. ideally parallelisable.
Being a fairly young language still
Go does not parallelise code by default. If CPU parallelism is desired one must tell the run-time how many goroutines shall execute simultaneously.
The code I wrote starts each calculation in a separate goroutine and allows the user to specify the number of CPUs/cores that should be used to execute the program.
Using a bash script I ran the resulting program varying both the number of calculations and the number of CPU cores.
These experiments were conducted on a 32-core server (Quad-Core AMD Opteron Processor 8356) with 64GB of RAM running
Ubuntu 11.04 server. Also, I ran each configuration for three consecutive times and used the average duration in the graph below.
golang run-time was not able to utilise more than 8 cores when running this particular program.
As can be seen from the graph (full size) above, executing the program on more than 8 cores did not decrease its running time futher.
200K calculations input file is a bit over half a gigabyte so I suspected that the program is dominated by I/O and the goroutines cannote execute because the result channel is full.
However, varying the result channel sizes did not seem to have a big effect.
Anyway, I am pretty happy with the code at this point but suggestions are always welcome, particularly those aiming at improving the degree of parallelism :-)
I am amazed how far I got by investing approx. 10 hours in learning
Go and programming in it.
python almost exclusively for the last 5 years I am pretty spoiled when it comes to code conciseness and productivity.
Go is not too far away though, and, programming in it was fun and enjoyable.
I will definitely continue to explore it. Maybe you should give it a whirl as well :-)