Strings and I/O: Zero-Allocation Conversions and Buffer Choices
Strings and I/O: Zero-Allocation Conversions and Buffer Choices
Zero-allocation conversion between string and []byte
func String(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
func Str2Bytes(s string) []byte {
x := (*[2]uintptr)(unsafe.Pointer(&s))
h := [3]uintptr{x[0], x[1], x[1]}
return *(*[]byte)(unsafe.Pointer(&h))
}I/O Operations
bufio.Reader vs bytes.Buffer
bufio reduces system calls for read and write operations by wrapping io.Reader and io.Writer interfaces. bytes.Buffer stores variable-length []byte slices efficiently.
bytes.Buffer vs strings.Builder
For Go 1.10 and later, use strings.Builder to store variable-length []byte slices. This avoids expensive copying. strings.Builder appends directly to its underlying array and returns strings with zero allocation.
strings.Builder’s growth strategy:
- If growth length N is ≤ cap-len, don’t expand
- Otherwise allocate new underlying array with capacity 2*cap + N and copy old data
Note that neither is safe for concurrent writes.