Как стать автором
Обновить

Комментарии 6

Я бы проголосовал за первые два (оба) варианта.
За пул из канала с буфером — отдельное спасибо.
Меня вот давно интересует вопрос — а по какому принципу происходит очистка данных из стандартного пула? То есть как он определяет, что вот сейчас наступил момент, когда данных в пуле ровно столько, что надо удалить лишнее? И удаляет ли он при это всё, что есть сейчас в пуле или только какую-то часть?
Спасибо за статью. Было бы здорово ещё добавить визуализации работы GC в случае без и с sync.Pool с помощью gcvis

Что-то вроде такого:
image.
Чёт не получилось у меня красивых графиков (c и без). Хотя бенчмарки радуют:
Benchmark_withoutPool-2   3000000  4209 ns/op  2390 B/op  3 allocs/op
Benchmark_withPool-2     10000000  1736 ns/op   692 B/op  1 allocs/op

Код и бенч на pastebin.com
Спасибо!

sync.Pool не панацея

Точно! Если можно применить простое не «goroutine-safe» переиспользование – получится быстрее.
Важный момент — если делать так, как указано в статье, то на каждую запись в пуле будет выделяться 32 байт в куче.

Замечу, что в официальном примере в пуле хранится (*bytes.Buffer).

Это все связано с тем, что при преобразовании структур данных типа []byte к interface{} метаданные структуры «убегают» в кучу. Таким образом, в пул надо записывать нечто, что сразу указывает на кучу, например, (* bytes.Buffer). Можно записывать указатели на что-то попроще:

type myBuffer struct{
    b []byte
}
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.