Golang Generics Performance Evaluation and Implications
Generics is the latest upcoming feature in Golang. Introducing high level elegant syntax along with infinite possibilities. If you need an introduction kindly visit our post on Golang generics.
Unlike the previous post, This post is more concerned about evaluating the performance of Golang Generics and some future perspectives and implications. Any source code snippets used in this post can be found here. The rest of the post is organized as follows:
- Introduction to generics
- Benchmark experiments strategy
- Benchmark results
- Implications on Golang future
Introduction to generics
Generics has been around and used extensively (specially when writing libraries or frameworks) in many programming languages like c++, c#, java. However, generics are known to have some extra computational cost to explicitly typed code. With that in mind, it has been always a good idea to write in generics rather than explicit coding due to its huge advantages in readability, maintainability and code reuse.
The introduction of generics in Golang may raise many questions regarding its performance, backward compatibility, updating currently used standard libraries (which are build on interfaces and reflections) and whether it is worth it to use generics in Golang. To find the answers to this and more keep reading.
Designing the performance benchmark experiment
We will consider evaluating both time and memory costs in these two situations:
- light weight simple operations
- computationally demanding operations
And for each one of the previously aforementioned scenarios, we will compare the cost of using generics to the cost of using explicit typing and legacy interfaces.
Simple tasks
For a simple operation we might consider a task of adding two numbers. The next three code snippets will demonstrate the use of explicit type style, generic style and the legacy interface style respectively.
The Benchmarking code for these samples is demonstrated in the next three code snippets in the same order
For a computationally expensive task we have selected the famous "Fibonacci" in its naïve implementation. As we did with the simple task evaluation, we are implementing three versions: an explicit style, a generic style and a legacy interface style. The code for these variations is listed below in a respective order along with their benchmark code.
Benchmark results
Testing environment :
Simple task analysis:
As we may have noticed in the above figure, both the generic and explicit implementations had almost the same execution time and number of memory allocations which is rather impressive performance for a generic function compared to a an explicitly typed function. The legacy interface function came far behind them in terms of both memory and cpu time. The graph below compares the running time of these tasks in a bar plot graph.
Expensive task analysis:
Which lead to the next section of this post, how will this affect the language, it's usability and standard libraries?
Implications on Golang future
- currently written Golang standard libraries
- currently running code in production servers
- code that will be written in the future
Currently written Golang standard libraries
Currently running code in production servers
If the previous assumption will evaluate to true, that means a lot of currently written packages that use Golang native libraries will break and will not be able to upgrade to the next version of go without considerable changes in their software artifacts.
Comments
Post a Comment