package main import ( "fmt" "runtime" "testing" "unsafe" ) func toBytes(s string) []byte { if len(s) == 0 { return nil } return unsafe.Slice(unsafe.StringData(s), len(s)) } func toString(b []byte) string { if len(b) == 0 { return "" } return unsafe.String(unsafe.SliceData(b), len(b)) } func toReflectBytes(s string) []byte { if len(s) == 0 { return nil } x := (*[2]uintptr)(unsafe.Pointer(&s)) h := [3]uintptr{x[0], x[1], x[1]} return *(*[]byte)(unsafe.Pointer(&h)) } func toReflectString(b []byte) string { if len(b) == 0 { return "" } return *(*string)(unsafe.Pointer(&b)) } func toK8sBytes(s string) []byte { return *(*[]byte)(unsafe.Pointer(&s)) } func toK8sString(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } func toRawBytes(s string) []byte { if len(s) == 0 { return nil } return []byte(s) } func toRawString(b []byte) string { if len(b) == 0 { return "" } return string(b) } var s = "hello, world" var bts = []byte("hello, world") func BenchmarkStringToBytesUnsafe(b *testing.B) { for i := 0; i < b.N; i++ { toBytes(s) } } func BenchmarkBytesToStringUnsafe(b *testing.B) { for i := 0; i < b.N; i++ { toString(bts) } } func BenchmarkStringToBytesReflect(b *testing.B) { for i := 0; i < b.N; i++ { toReflectBytes(s) } } func BenchmarkBytesToStringReflect(b *testing.B) { for i := 0; i < b.N; i++ { toReflectString(bts) } } func BenchmarkStringToBytesK8s(b *testing.B) { for i := 0; i < b.N; i++ { toK8sBytes(s) } } func BenchmarkBytesToStringK8s(b *testing.B) { for i := 0; i < b.N; i++ { toK8sString(bts) } } func BenchmarkStringToBytesRaw(b *testing.B) { for i := 0; i < b.N; i++ { toRawBytes(s) } } func BenchmarkBytesToStringRaw(b *testing.B) { for i := 0; i < b.N; i++ { toRawString(bts) } } func TestGC(t *testing.T) { for i := 0; i < 1000; i++ { b := toBytes(s) runtime.GC() if b[11] != 'd' { t.Errorf("want %c, got %c", 'd', b[11]) } ss := toString(bts) runtime.GC() if ss != s { t.Errorf("want %s, got %s", s, ss) } } for i := 0; i < 1000; i++ { b := toReflectBytes(s) runtime.GC() if b[11] != 'd' { t.Errorf("want %c, got %c", 'd', b[11]) } ss := toReflectString(bts) runtime.GC() if ss != s { t.Errorf("want %s, got %s", s, ss) } } for i := 0; i < 1000; i++ { b := toK8sBytes(s) runtime.GC() if b[11] != 'd' { t.Errorf("want %c, got %c", 'd', b[11]) } ss := toK8sString(bts) runtime.GC() if ss != s { t.Errorf("want %s, got %s", s, ss) } } for i := 0; i < 1000; i++ { b := toRawBytes(s) runtime.GC() if b[11] != 'd' { t.Errorf("want %c, got %c", 'd', b[11]) } ss := toRawString(bts) runtime.GC() if ss != s { t.Errorf("want %s, got %s", s, ss) } } } func Test_toK8sBytes(t *testing.T) { a := *(*[3]int64)(unsafe.Pointer(&s)) fmt.Printf("%d, %d, %d\n", a[0], a[1], a[2]) b := *(*[]byte)(unsafe.Pointer(&s)) fmt.Printf("%d, %d, %d\n", unsafe.SliceData(b), len(b), cap(b)) b = append(b, '!') }