All Benchmarks

Go Benchmark

String to Bytes Conversion

The cost of []byte(s) and string(b) — and the unsafe zero-copy alternative.

stringbytesconversionunsafezero-copyallocation

Converting between string and []byte is everywhere in Go: hashing, writing to sockets, JSON encoding. Because strings are immutable, the standard conversions []byte(s) and string(b) allocate and copy the entire payload every time. Since Go 1.20, unsafe.String and unsafe.Slice (with unsafe.StringData / unsafe.SliceData) allow reinterpreting the same memory with zero copies — the same trick the standard library uses internally in strings.Builder. This benchmark shows what the safe conversions cost for a 128-byte payload and what the unsafe route saves. The "Bytes" tab converts string → []byte, the "String" tab converts []byte → string.

linux/amd64AMD Ryzen 9 9950X3D 16-Core Processorbenchmarks/string-to-bytes
Compare atCPUs

1 CPU

Bytes

Fastest

Unsafe Zero Copy

0.56 ns/op

Slowest

Standard Conversion

26.73 ns/op · 47x slower

String

Fastest

Unsafe Zero Copy

0.37 ns/op

Slowest

Standard Conversion

11.5 ns/op · 31x slower

32 CPUs

Bytes

Fastest

Unsafe Zero Copy

0.58 ns/op

Slowest

Standard Conversion

15.69 ns/op · 27x slower

String

Fastest

Unsafe Zero Copy

0.35 ns/op

Slowest

Standard Conversion

18.43 ns/op · 52x slower

Performance Comparison (lower is better)
CPU:

Unsafe Zero Copy #

Fastest (Bytes)Fastest (String)

Uses unsafe.Slice(unsafe.StringData(s), len(s)) and unsafe.String(unsafe.SliceData(b), len(b)) to reinterpret the existing memory: no allocation, no copy, constant time regardless of size. The contract is on you: mutating the resulting bytes (or the source slice) is undefined behavior. Only reach for this on measured hot paths where the data is provably never modified.

Performance (lower is better)
CPU:
// sampleString is a typical medium-sized payload (exactly 128 bytes).
const sampleString = "In Go, converting between a string and a []byte copies all bytes, " +
	"because strings are immutable while byte slices are mutable..."

func BenchmarkUnsafeZeroCopy_bytes(b *testing.B) {
	for i := 0; i < b.N; i++ {
		// Reinterprets the string's backing memory as a []byte without copying.
		// The result must never be mutated — strings are immutable.
		sinkBytes = unsafe.Slice(unsafe.StringData(sampleString), len(sampleString))
	}
}

func BenchmarkUnsafeZeroCopy_string(b *testing.B) {
	data := []byte(sampleString)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Reinterprets the byte slice's backing memory as a string without copying.
		// The slice must never be mutated afterwards.
		sinkString = unsafe.String(unsafe.SliceData(data), len(data))
	}
}
1 CPU

Bytes

47.4xfaster(4641%)thanStandard Conversion

String

31.4xfaster(3044%)thanStandard Conversion
32 CPUs

Bytes

27.1xfaster(2609%)thanStandard Conversion

String

52.4xfaster(5143%)thanStandard Conversion

Standard Conversion #

Slowest (Bytes)Slowest (String)

The built-in conversions []byte(s) and string(b). Each one allocates fresh memory and copies the whole payload, because the compiler must guarantee that the immutable string and the mutable slice never share memory. Safe, idiomatic, and the right default — the cost scales with payload size.

Performance (lower is better)
CPU:
// sampleString is a typical medium-sized payload (exactly 128 bytes).
const sampleString = "In Go, converting between a string and a []byte copies all bytes, " +
	"because strings are immutable while byte slices are mutable..."

func BenchmarkStandardConversion_bytes(b *testing.B) {
	for i := 0; i < b.N; i++ {
		// Allocates a new byte slice and copies the string data into it.
		sinkBytes = []byte(sampleString)
	}
}

func BenchmarkStandardConversion_string(b *testing.B) {
	data := []byte(sampleString)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Allocates a new string and copies the slice data into it.
		sinkString = string(data)
	}
}
1 CPU

Bytes

47.4xslower(4641%)thanUnsafe Zero Copy

String

31.4xslower(3044%)thanUnsafe Zero Copy
32 CPUs

Bytes

27.1xslower(2609%)thanUnsafe Zero Copy

String

52.4xslower(5143%)thanUnsafe Zero Copy

Contributors