Go string和[]byte高效内存转换

string与[]byte的直接转换是通过底层数据copy实现的,在数据量较大时存在一定的消耗,其实存在更高效的转换方式:利用底层指针之间的转换,没有额外的内存分配,性能大大提升。
要实现这个目的,必须对string和[]byte底层结构深入了解:

struct string {
    uint8 *str;
    int len;
}

struct []uint8 {
    uint8 *array;
    int len;
    int cap;
}

string 可看做 [2]uintptr,而 [ ]byte 则是 [3]uintptr,这便于我们编写代码,无需额外定义结构类型。如此,str2bytes 只需构建 [3]uintptr{ptr, len, len},而 bytes2str 更简单,直接转换指针类型,忽略掉 cap 即可

package main

import (
    "fmt"
    "strings"
    "unsafe"
)

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))
}

func bytes2str(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}

func main() {
    s := strings.Repeat("abc", 3)
    b := str2bytes(s)
    s2 := bytes2str(b)
    fmt.Println(b, s2)
}

你可能感兴趣的:(Go string和[]byte高效内存转换)