// convert b to string without copy funcBytesString(b []byte)String { return *(*String)(unsafe.Pointer(&b)) }
// returns &s[0], which is not allowed in go funcStringPointer(s string)unsafe.Pointer { p := (*reflect.StringHeader)(unsafe.Pointer(&s)) return unsafe.Pointer(p.Data) }
// returns &b[0], which is not allowed in go funcBytesPointer(b []byte)unsafe.Pointer { p := (*reflect.SliceHeader)(unsafe.Pointer(&b)) return unsafe.Pointer(p.Data) }
func TestPointer(t *testing.T) { s := []string{ "", "", "hello", "hello", fmt.Sprintf(""), fmt.Sprintf(""), fmt.Sprintf("hello"), fmt.Sprintf("hello"), } fmt.Println("String to bytes:") for i, v := range s { b := unsafe.StringBytes(v) b2 := []byte(v) if b.Writeable() { b[0] = 'x' } fmt.Printf("%d\ts=%5s\tptr(v)=%-12v\tptr(StringBytes(v)=%-12v\tptr([]byte(v)=%-12v\n", i, v, unsafe.StringPointer(v), b.Pointer(), unsafe.BytesPointer(b2)) }
b := [][]byte{ []byte{}, []byte{'h', 'e', 'l', 'l', 'o'}, } fmt.Println("Bytes to string:") for i, v := range b { s1 := unsafe.BytesString(v) s2 := string(v) fmt.Printf("%d\ts=%5s\tptr(v)=%-12v\tptr(StringBytes(v)=%-12v\tptr(string(v)=%-12v\n", i, s1, unsafe.BytesPointer(v), s1.Pointer(), unsafe.StringPointer(s2)) }
}
const N = 3000000
func Benchmark_Normal(b *testing.B) { for i := 1; i < N; i++ { s := fmt.Sprintf("12345678901234567890123456789012345678901234567890") bb := []byte(s) bb[0] = 'x' s = string(bb) s = s } } func Benchmark_Direct(b *testing.B) { for i := 1; i < N; i++ { s := fmt.Sprintf("12345678901234567890123456789012345678901234567890") bb := unsafe.StringBytes(s) bb[0] = 'x' s = s } }