Interfaces in Go are costly … let’s understand why ⚡
Go, although being a strongly typed language, allows defining methods that accept generic interface types, providing us the flexibility to accept data of any type; but this is inefficient, and here’s why …
When we store values as interfaces, each value needs to be stored as the value itself, and then two “words” are added for the interface pointing to that value and its type. For a 64-bit machine, the word is 8 bytes so 2 words imply 16 bytes of additional data.
This extra overhead can increase memory usage, especially if we are storing large numbers of smaller values in our data structure.
Say, for a B Tree implementation, we define a node that holds the value of any type, we provide it a type interface{}. When we are storing the value, we are taking an overhead of two words = 16 bytes.
Since interfaces can point to values anywhere in memory, values are most likely not stored in the contiguous memory block. This results in a higher number of cache misses, which can negatively impact performance, especially when working with large datasets.
This is precisely why, it is recommended to avoid storing values as interfaces unless absolutely necessary and pass them by their absolute types. By the way …
I stumbled upon this inefficiency while I was browsing CockroachDB’s source code to go deeper into their usage of BTrees for holding some indexes.
Hope you found it amusing. Be curious … because engineering is beautiful.
⚡ I keep writing and sharing my practical experience and learnings every day, so if you resonate then follow along. I keep it no fluff.
youtube.com/c/ArpitBhayani