Пакет unique
Пакет unique (Go 1.23+) помогает сэкономить память, если обрабатываются неуникальные значения.
Рассмотрим пример. У нас есть генератор слов:
const nDistinct = 100
const wordLen = 40
generate := wordGen(nDistinct, wordLen)
fmt.Println(generate())
// nlfgseuif...
fmt.Println(generate())
// anixapidn...
fmt.Println(generate())
// czedtcbxa...
Размер словаря ограничен (100 слов), так что генерируемые значения будут часто повторяться.
Сгенерим 10000 слов и запишем их в срез строк:
words = make([]string, nWords)
for i := range nWords {
words[i] = generate()
}
Memory used: 622 KB
10К слов заняли 600 Кб в куче.
Попробуем другой подход. Используем unique.Handle
, чтобы назначить дескриптор каждому уникальному слову, и будем хранить эти дескрипторы вместо самих слов:
words = make([]unique.Handle[string], nWords)
for i := range nWords {
words[i] = unique.Make(generate())
}
Memory used: 95 KB
100 Кб вместо 600 Кб — в 6 раз меньше памяти.
Функция Make
создает уникальный дескриптор для значения любого comparable-типа. Она возвращает ссылку на «каноническую» копию значения в виде объекта Handle.
Два Handle
равны только в том случае, если равны исходные значения. Сравнение двух Handle
эффективно, потому что сводится к сравнению указателей.
Под капотом пакет unique
ведет глобальный конкурентно-безопасный кеш всех добавленных значений, гарантируя их уникальность и повторное использование.
★ Подписывайтесь на новые заметки.