原文地址
https://commaok.xyz/post/intern-strings/
go中对这块的支持几乎没有,为什么如此呢,博主主要是评价:
假设你想重新使用一个单独的数据hello副本?这就是字符串互连。互插字符串有两个好处。一个明显的优点是你不需要分配和复制数据。另一个是,它可以加快字符串的平等性检查速度。如果两个字符串的长度和数据指针相同,那么它们是相等的;不需要实际检查字节。
从Go 1.14开始,Go不对大多数字符串进行内嵌。像任何形式的缓存一样,内嵌也是有代价的:并发安全的同步,垃圾回收器的复杂性,以及每次创建字符串时要执行的额外代码。而且,就像缓存一样,在有些情况下,它是有害的而不是有帮助的。如果你在处理一个字典词的列表,没有一个词会出现两次,因此对字符串进行互连是浪费时间和内存。
func main() { b := []byte("hello") s := string(b) t := string(b) // 824634236680 fmt.Println(pointer(s)) // 824634236648 fmt.Println(pointer(t)) } func pointer(s string) uintptr { p := unsafe.Pointer(&s) h := *(*reflect.StringHeader)(p) return h.Data }
可以用map来实现逻辑上的intern
func intern(m map[string]string, b []byte) string { c, ok := m[string(b)] if ok { return c } s := string(b) m[s] = s return s }
end