Почему string.Builder Reset () не сохраняет базовый буфер? - PullRequest
0 голосов
/ 30 апреля 2020
// Reset resets the Builder to be empty.
func (b *Builder) Reset() {
    b.addr = nil
    b.buf = nil
}

Фрагмент кода из исходного кода в go строках. Строитель . Буфер установлен на nil вместо b.buf[:0]. Какая причина была бы установить его на nil вместо сохранения емкости?

РЕДАКТИРОВАТЬ: Я вижу, что Reset() может использоваться для G C базового буфера и разрешить повторное использование структуры Builder, но кажется, что инициализация структуры требует дополнительных затрат, поскольку она состоит всего из двух указателей, тогда как базовый массив мог бы быть намного больше и мог бы быть использован повторно. Я чувствую, что должна была быть функция Clear(), которая сохраняла емкость основного буфера, но уменьшала его длину до 0, и это было бы тривиально реализовать. Это заставляет меня верить, что есть причина, почему это не было сделано, и мне любопытно, что это за причина.

Ответы [ 3 ]

1 голос
/ 01 мая 2020

Одной из оптимизаций 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

0 голосов
/ 30 апреля 2020

Если Reset сохраняет базовый буфер, то долгоживущий Builder займет память для самой длинной строки, которую он когда-либо создавал. Массив, выделенный для самой длинной строки, всегда будет живым, даже если большая его часть останется неиспользованной. Установка буфера в ноль позволяет сборщику мусора собирать такие потенциальные большие буферы.

0 голосов
/ 30 апреля 2020

Точка Reset() - для перевода Builder в исходное пустое состояние (как при создании нового).

Преимущество этого вместо получения нового Builder заключается в том, что другие компоненты вашей программы хранят ссылку на существующий Builder, и вы хотите "сбросить" его до исходного состояния, не обновляя все эти компоненты с помощью новая ссылка.

...