Ответ вслух Senior Строки, байты и руны обновлено

Производительность работы со строками

Вопрос

Сервис много собирает и разбирает строки, профиль показывает много аллокаций в этом коде. Какие приёмы оптимизации вы примените?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Начинаю с замера: бенчмарк с -benchmem и heap-профиль по allocspace показывают, какие строки рождают аллокации. Дальше по шагам.

Что должно прозвучать в ответе

  • Сначала профиль: 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 ошибок.