[英]Why Golang string.Builder String() can convert []byte to slice without a reflect.StringHeader?
[英]Why doesn’t string.Builder Reset() preserve the underlying buffer?
// Reset resets the Builder to be empty.
func (b *Builder) Reset() {
b.addr = nil
b.buf = nil
}
代碼片段來自go strings.Builder中的源代碼。 緩沖區設置為nil
而不是b.buf[:0]
。 將其設置nil
而不是保留容量的原因是什么?
編輯:我可以看到Reset()
可用於 GC 底層緩沖區並允許重新使用 Builder 結構,但初始化結構似乎是邊際成本,因為它只是兩個指針,而底層數組可能要大得多,並且可以重復使用。 我覺得應該有一個Clear()
function 保持底層緩沖區的容量但將其長度減少到 0,並且實現起來很簡單。 這讓我相信為什么沒有這樣做是有原因的,我很好奇這個原因是什么。
strings.Builder
的優化之一是它在將[]byte
轉換為string
時不會復制字節。 看一下它的String()
方法:
// String returns the accumulated string.
func (b *Builder) String() string {
return *(*string)(unsafe.Pointer(&b.buf))
}
這意味着重用緩沖區會破壞以前創建的字符串。
這是操場上的證明: https://play.golang.org/p/gkSXRwi0-Ff
Reset()
的要點是讓Builder
初始為空 state (就像創建新的一樣)。
這樣做而不是獲取新Builder
的好處是,當您的程序的其他組件持有對現有Builder
的引用並且您想要將其“重置”為初始 state 而不用新引用刷新所有這些組件時。
如果Reset
保留底層緩沖區,那么長壽命的Builder
將占用 memory 以獲得它所構建的最長字符串。 為最長字符串分配的數組將始終處於活動狀態,即使其中大部分未被使用。 將緩沖區設置為 nil 允許垃圾收集器收集這些潛在的大緩沖區。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.