Bytes to String Quickly
...大约 1 分钟
Using unsafe
package to convert byte
slice to string
is more efficient than type conversion.
unsafe.Pointer
(Recommended)
1. func BytesToStringUnsafePointer(buf []byte) string {
return *(*string)(unsafe.Pointer(&buf))
}
unsafe.String(ptr *byte, len IntegerType) string
(Recommended v1.20)
2. After go v1.20
func BytesToStringUnsafePointer2(buf []byte) string {
return unsafe.String(unsafe.SliceData(buf), len(buf))
}
3. Type Conversion
func BytesToStringTypeConvert(buf []byte) string {
return string(buf)
}
Benchmark
func BenchmarkBytesToString(b *testing.B) {
tests := []struct {
name string
f func([]byte) string
}{
{name: "UnsafePointer", f: BytesToStringUnsafePointer},
{name: "UnsafePointerV1.20", f: BytesToStringUnsafePointer2},
{name: "TypeConvert", f: BytesToStringTypeConvert},
}
for k := 10; k <= 100000; k *= 10 {
buf := genBytes(k)
for _, t := range tests {
b.Run(fmt.Sprintf("%-20s_%.e", t.name, float64(k)), func(b *testing.B) {
for i := 0; i < b.N; i++ {
t.f(buf)
}
})
}
}
}
func genBytes(length int) []byte {
letters := make([]byte, 0, 26)
var c byte = 'a'
for ; c <= 'z'; c++ {
letters = append(letters, c)
}
buf := make([]byte, 0, length)
for i := 0; i < length; i++ {
idx := rand.Intn(26)
buf = append(buf, letters[idx])
}
return buf
}
unsafe
package (Not Recommended)
4. Bytes To String using If convert []byte
to string
using unsafe
package, it will cause runtime error: unexpected fault address: xxxxx, fatal error: fault
func main() {
s := "abc"
buf := StringToBytesUnsafePointer(s)
printBufInfo(buf)
buf2 := StringToBytesUnsafePointer2(s)
printBufInfo(buf2)
// unexpected fault address
sort.Slice(buf, func(i, j int) bool {
return buf[i] > buf[j]
})
// unexpected fault address
sort.Slice(buf2, func(i, j int) bool {
return buf2[i] > buf2[j]
})
}
func StringToBytesUnsafePointer(s string) []byte {
return *(*[]byte)(unsafe.Pointer(&s))
}
func StringToBytesUnsafePointer2(s string) []byte {
return unsafe.Slice(unsafe.StringData(s), len(s))
}
func printBufInfo(buf []byte) {
format := "%p, %v, len: %d, cap: %d \n"
fmt.Printf(format, &buf, buf, len(buf), cap(buf))
}
Output:
*(*[]byte)(unsafe.Pointer(&s))
: will create a capacity unexpected slice
Reference
Powered by Waline v2.15.2