13

I have this text which I would like to put into a byte slice:

s := "There are these two young fish swimming along and they happen to meet an older fish swimming the other way"

If I write

b := []byte("There are these two young fish swimming along and they happen to meet an older fish swimming the other way")

As I understand, at runtime this will:

  1. create a string with the values in memory
  2. create a byte slice
  3. copy the contents of the string into the byte slice (reallocating as necessary)

I could convert each of the string values to their ASCII equivalent and create the byte slice directly:

b := []byte{84, 104, ... }

though this isn't very readable.

I understand that the example here is a little trivial and most computers can do this in a flash, but I'm curious about it. Does the compiler interpret []byte("blah") and turn it into an efficient byte slice at compile time? Would the best solution change if the string included non-ASCII characters?

Kevin Burke
  • 61,194
  • 76
  • 188
  • 305
  • 1
    Are these conversions part of your innermost computation loop? Is this the bottleneck which showed up in profiling? Is GC slow because you generate too much garbage by this conversions? If no: Why bother? – Volker Sep 05 '14 at 22:38
  • "Would the best solution change if the string included non-ASCII characters?" No. Go source is utf8; things like the `for _, chr := range str {...}` loop handle utf8; your program probably won't have to make any special provisions to handle utf-8. – twotwotwo Sep 05 '14 at 23:54
  • 1
    Don't think it will "reallocate as necessary" because it already knows how many bytes are in the string, so it can grab enough memory up front. Listing out the bytes seems like a very bad idea (makes your source code ugly) and I'm not sure it executes even infinitesimally more efficiently; since byte slices are mutable, the bytes might still need to be copied from constant-land to heap memory. Also, as Volker says, any nanoseconds spent copying at startup are not a big deal. – twotwotwo Sep 06 '14 at 00:10
  • Volker, because I'm new to the language, and I'm wondering what's actually going on. – Kevin Burke Sep 06 '14 at 01:04
  • PeterSO's answer looks good here then. Rob Pike has a great post on how Go strings work, including non-ASCII characters, at http://blog.golang.org/strings – twotwotwo Sep 06 '14 at 04:34

2 Answers2

5

Go embeds the string in the executable program as a string literal. It converts the string literal to a byte slice at runtime using the runtime.stringtoslicebyte function.

peterSO
  • 158,998
  • 31
  • 281
  • 276
4

If you are initialising a []byte variable from a constant string, it looks like the compiler is smart enough not to create an intermediate string: instead, the backing array for the byte slice is initialised directly from static data rather than constructing a string variable first.

There is a data copy, but that is to be expected when constructing a mutable type.

James Henstridge
  • 42,244
  • 6
  • 132
  • 114