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

当我可以连接字符串时,为什么要使用缓冲区?


下面的伪代码


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)


呼如林
浏览 214回答 3
3回答

人到中年有点甜

缓冲区成块增长以分摊内存分配。因为字符串是不可变的,所以每次循环迭代都必须分配一个新字符串。

Cats萌萌

您可以将缓冲区视为一个队列,您可以在其中将事物排成一行。每个人都只是一个接一个地排成一排,非常高效,并且不会占用额外的空间来添加新项目。您只需插入它们即可完成。因此,当您将 A、B、C、D、E 添加到缓冲区时,操作看起来有点像这样的内存明智:buffer=Abuffer=A|Bbuffer=A|B|Cbuffer=A|B|C|Dbuffer=A|B|C|D|E现在,如果您连接字符串,则必须分配和重新分配大量内存&nbsp;str=''&nbsp;str=Allocate(A),allocate(str+A),deallocate(str='')&nbsp;str=Allocate(B),allocate(str(''|A)+B),deallocate(str=''|A)&nbsp;str=Allocate(C),allocate(str(''|A|B)+C),deallocate(str=''|A|B)&nbsp;str=Allocate(D),allocate(str(''|A|B|C)+D),deallocate(str=''|A|B|C)&nbsp;str=Allocate(E),allocate(str(''|A|B|C|D)+E),deallocate(str=''|A|B|C|D)如您所见,通过不断向字符串添加一个由旧字符串组成的新字符串,然后创建新字符串并释放旧字符串。这会导致大量垃圾内存。当您添加缓冲区时,您只需将所有内容整齐地排列起来,而不会占用太多额外的内存。虽然如果您连接字符串,您会不断分配更新和更大的变量。旧字符串 + 追加字符串 + 新连接字符串。这不断增长,不断增长,不断增长。如果你有一个大文件,你逐行读取,这可能会在一段时间后出现一些内存不足的错误。

江户川乱折腾

字符串在 Go 中是不可变的。因此,第二个示例将在每次迭代时分配一个新字符串,因此运行时间为 O(n^2)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go