Производительность работы со строками
Вопрос
Сервис много собирает и разбирает строки, профиль показывает много аллокаций в этом коде. Какие приёмы оптимизации вы примените?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Сначала профиль: pprof alloc_space и бенчмарки с -benchmem
strings.Builder или bytes.Buffer с Grow вместо + и Sprintf
strconv.AppendInt и похожие Append-функции в общий буфер вместо Sprintf
Работа с []byte от начала до конца, без лишних конвертаций туда и обратно
sync.Pool для переиспользуемых буферов
Подстроки без копий, но с осторожностью к удержанию больших строк
Что могут спросить следом
- Почему fmt.Sprintf дороже strconv.Itoa?
- Когда оправдан unsafe.String?
Разбор
Начинаю с замера: бенчмарк с -benchmem и heap-профиль по alloc_space показывают, какие строки рождают аллокации. Дальше по шагам. Склейку через + и fmt.Sprintf заменяю на strings.Builder с Grow, когда размер примерно известен. Числа форматирую через strconv.AppendInt прямо в байтовый буфер, без промежуточных строк: Sprintf разбирает формат и упаковывает аргументы в интерфейсы, что тоже аллокации. Если данные пришли как []byte (из сети), стараюсь не конвертировать их в строку и обратно, работаю пакетом bytes. Буферы переиспользую через sync.Pool. Подстроки бесплатны, но держат исходную строку: если кусок живёт долго, делаю strings.Clone. unsafe.String применяю только в изолированном горячем месте, когда гарантирую, что байты не изменятся, и покрываю это тестами.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «Строки, байты и руны»
- Байты и символы в строке Go
- Разворот строки с кириллицей на Go
- Сжатие RLE для строк UTF-8 на Go
- Палиндром с кириллицей и знаками на Go
- Перенос текста по ширине в символах на Go
- Что выведет Go: len и range по строке с кириллицей
- Что выведет Go: руны, байты и преобразования
- Что выведет Go: сравнение и срезы строк