为了账号安全,请及时绑定邮箱和手机立即绑定

当我们可以存储在字符串变量中时,缓冲区的用途是什么?

当我们可以存储在字符串变量中时,缓冲区的用途是什么?

Go
呼如林 2021-12-06 19:50:40
当我可以连接字符串时,为什么要使用缓冲区?下面的伪代码var buffer bytes.Buffer for i := 0; i < 200; i++ {    buffer.WriteString(strconv.Itoa(i))}fmt.Println(buffer.String())对比buffer := ""for i := 0; i < 200; i++ {    buffer += strconv.Itoa(i)}fmt.Println(buffer)
查看完整描述

3 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

缓冲区成块增长以分摊内存分配。

因为字符串是不可变的,所以每次循环迭代都必须分配一个新字符串。


查看完整回答
反对 回复 2021-12-06
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

您可以将缓冲区视为一个队列,您可以在其中将事物排成一行。每个人都只是一个接一个地排成一排,非常高效,并且不会占用额外的空间来添加新项目。您只需插入它们即可完成。


因此,当您将 A、B、C、D、E 添加到缓冲区时,操作看起来有点像这样的内存明智:


buffer=A

buffer=A|B

buffer=A|B|C

buffer=A|B|C|D

buffer=A|B|C|D|E

现在,如果您连接字符串,则必须分配和重新分配大量内存


 str=''

 str=Allocate(A),allocate(str+A),deallocate(str='')

 str=Allocate(B),allocate(str(''|A)+B),deallocate(str=''|A)

 str=Allocate(C),allocate(str(''|A|B)+C),deallocate(str=''|A|B)

 str=Allocate(D),allocate(str(''|A|B|C)+D),deallocate(str=''|A|B|C)

 str=Allocate(E),allocate(str(''|A|B|C|D)+E),deallocate(str=''|A|B|C|D)

如您所见,通过不断向字符串添加一个由旧字符串组成的新字符串,然后创建新字符串并释放旧字符串。

这会导致大量垃圾内存。当您添加缓冲区时,您只需将所有内容整齐地排列起来,而不会占用太多额外的内存。


虽然如果您连接字符串,您会不断分配更新和更大的变量。旧字符串 + 追加字符串 + 新连接字符串。这不断增长,不断增长,不断增长。

如果你有一个大文件,你逐行读取,这可能会在一段时间后出现一些内存不足的错误。


查看完整回答
反对 回复 2021-12-06
?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

字符串在 Go 中是不可变的。因此,第二个示例将在每次迭代时分配一个新字符串,因此运行时间为 O(n^2)。


查看完整回答
反对 回复 2021-12-06
  • 3 回答
  • 0 关注
  • 213 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信