doudou2121
doudou2121
采纳率50%
2016-03-13 20:32 阅读 1.7k
已采纳

我应该如何在Golang中将切片转换为字符串?

我正在分裂一个字符串。

我希望我的程序保留数组的一个元素并释放底层数组。

不幸的是,我不知道如何将字符串的一个片段转换为不引用底层字符串的字符串。

我是不是应该这样做:

func unslice(s string) (string) {
  return string([]byte(s))
}

背景是:

  1. 底层的字符串非常大
  2. 我想保留的部分很小
  3. 我想保留的部分会保留很长时间
  4. 这个程序会运行很长一段时间,甚至更长时间
  5. 在程序的生命周期中,它将分割这些字符串中的许多(数百万)

下面是一个回应评论的例子:

func takesBigStringOften(big string) {
    parts := strings.Split(big, " ")

    saveTinyStringForALongTime(parts[0])
}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    duanfu7004 duanfu7004 2016-03-13 20:50

    To ensure that Go doesn't keep the underlying string in memory you will have to explicitly copy it to a new location:

    func unslice(old string) string {
        new := make([]byte,len(old))
        copy(new,old)
        return string(old)
    }
    
    SmallString := unslice(BigString[0:7])
    
    点赞 评论 复制链接分享
  • dongxing1412 dongxing1412 2016-03-14 17:13

    Just as some further information. Some benchmark code and memory profiling shows that as of go 1.5.3, both methods allocate the same amount of memory from the heap, i.e. a new copy is made either way. In building a string from a byte slice, the compiler calls a routine that makes a unique copy of the bytes - since strings are immutable and byte slices are not.

    $ 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:}
    
    点赞 评论 复制链接分享

相关推荐