2024-02-12

GO Myths we believe: Strings

Hi! Here is the second part of my “go myths” series. The first part can be read here.

Today I’m gonna to talk about strings. There are two popular myths about strings, and I want to share real state of affairs.

1. String is NOT the slice of bytes.

Yep, you can read everywhere that string is a slice of bytes, even on go.dev, but it’s just not true. Imagine, how will the string struct look like in this case? `type string []byte`? Maybe! But the source code is always the source of truth.

So, it’s definitely NOT a slice. It may look like it, but that’s as far as it goes.

2. Strings concatenations NOT always lead to allocations.

As you can hear, strings are immutable and that is why all concatenation operations lead to allocations. But it’s a very simplified thesis.

Let’s do some benchmarking:

Output:

Now we can be confident that no-allocation concatenations are possible. But how? Let’s ask our single source of truth in industry — the source code.

Here is the buffer. If the string is small enough to store the new value (inital + concatenated data) in 32 bytes, we will not get an allocation!

Output:

Now let’s force an allocation:

Output:

Gotcha! Here is how it’s decided to allocate or not.

It just compares the length of “l” (resulting string) with the size of buffer array. If “l” less than 32 bytes (for go 1.22) no allocation will happen, for another case calling “rawstring” leads to call “mallocgc” function.

Fun fact

Just change the concat syntax to “+=” and get an allocation!

Output:

Author: Herman Samolazov

You may also like:

GO Myths we believe: Capacity

Workflow engines 101

Go back