gpt4 book ai didi

go - 如何(深度)在 Go 中复制字符串?

转载 作者:行者123 更新时间:2023-12-03 10:09:45 32 4
gpt4 key购买 nike

我可能应该先解释一下为什么我想要那个。
我理解 Go 子字符串( s[i:j] )和 string.Split和其他一些字符串操作就地工作:生成的子字符串共享原始字符串的相同内存块。
例如,我读取一个大字符串,解析并从中获取一些子字符串,这些子字符串将长期保存在服务器程序中,它们将“持有”来自 GC 的大内存块,浪费内存。我假设如果我可以复制这些子字符串并保留这些副本,GC 可以释放那个大字符串。
但是我在Go中找不到字符串复制机制,我尝试将其转换为[]byte然后 string同样,在我的特定用例中,内存使用量下降了大约 3/4。
但这感觉不对:
第一,它介绍了两种复制操作。
第二,由于我从未真正写入该 byte slice ,我怀疑它可能会在发布版本中得到优化。
我无法想象以前没有人问过这个问题,但是我的搜索没有产生任何相关的结果,或者在 Go 中有一些更好的做法来做这些事情吗?
顺便说一句,我尝试向它附加一个空字符串( +"" ),内存消耗并没有下降,我认为即使在测试版本中它也得到了优化。
为了测量内存使用情况,我调用 runtime.GC()然后 runtime.ReadMemStats()并比较 MemStats.Alloc ,这在我的测试中似乎非常一致。

最佳答案

字符串被实现为指向底层字节数组和字符串长度的指针。当您从现有字符串创建 slice 时,新字符串仍指向基础数组,可能指向该数组中具有不同长度的不同偏移量。这样,许多小字符串可以使用单个底层大数组。
正如您所指出的,如果您有一个大字符串并将其解析为较小的字符串,那么您最终会将大字符串保留在内存中,因为 GC 只知道底层数组和指向它的指针。有两种方法可以处理这个问题:

  • 不要使用大字符串,而是保留 []byte或使用基于字节流的阅读器/扫描器,并在解析时从输入创建字符串。这样 GC 将收集底层的 []byte解析完成后,您将拥有没有底层大块的字符串。
  • 执行您已经描述的操作,并使用 string([]byte(s[x:y])) 深度复制字符串, 或使用 copy .
  • 关于go - 如何(深度)在 Go 中复制字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65419268/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com