我正在使用 strings.Split 来分割字符串。
我希望我的程序保留数组的元素之一并释放底层数组。
不幸的是,我不知道如何将字符串 slice 转换为不引用底层字符串的字符串。
我应该做这样的事情吗:
func unslice(s string) (string) {
return string([]byte(s))
}
背景是:
- 底层字符串非常大
- 我要保留的 slice 很小
- 我想保留的 slice 会保留很长时间
- 该程序将运行很长时间 - 几周或更长时间
- 在程序的生命周期内,它将分割许多这样的字符串(数百万个)
这是回应评论的示例。
func takesBigStringOften(big string) {
parts := strings.Split(big, " ")
saveTinyStringForALongTime(parts[0])
}
最佳答案
就像一些进一步的信息一样。一些基准代码和内存分析显示,从 go 1.5.3 开始,两种方法都从堆中分配相同数量的内存,即无论哪种方式都会创建一个新副本。在从字节 slice 构建字符串时,编译器调用一个例程来制作字节的唯一副本 - 因为字符串是不可变的,而字节 slice 不是。
$ go tool pprof -alloc_space so002.test cprof0
Entering interactive mode (type "help" for commands)
(pprof) list copy
Total: 9.66MB
9.62MB 9.62MB (flat, cum) 99.55% of Total
. . 15:
. . 16:var global string
. . 17:
. . 18:func benchmarkcopy(b *testing.B, c int) {
. . 19: big := "This is a long string"
. 240B 20: parts := strings.Split(big, " ")
. . 21: old := parts[0]
. . 22: jlimit := 100
. . 23: for i := 0; i < b.N; i++ {
. . 24: for j := 0; j < jlimit; j++ {
3.21MB 3.21MB 25: global = string([]byte(old))
. . 26: }
. . 27: for j := 0; j < jlimit; j++ {
. . 28: b := []byte(old)
3.21MB 3.21MB 29: global = string(b)
. . 30: }
. . 31: for j := 0; j < jlimit; j++ {
3.21MB 3.21MB 32: new := make([]byte, len(old))
. . 33: copy(new, old)
. . 34: global = string(old)
. . 35: }
. . 36: }
. . 37:}
关于go - golang 中如何将 slice 转换为字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35975456/