Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!08.08.2024
Оптимізація структур даних Go в памʼяті
В продовження вчорашньої ситуації: ділюся декількома знахідками.
-
З динамічних мов як Ruby чи JavaScript можна звикнути, що обʼєкти та “словники” працюють хоч приблизно однаково. В Golang це абсолютно не так. Структура фундаментально економніша. Особливо це стосується маленьких структур. Наприклад, бачив словники з двох ключів-констант; можу припустити, що так їх простіше було завантажити чи побудувати. Але “словник зі сталими ключами” в Go - це структура.
-
Звісно, ще гірше, коли такий словник не один, а повторюється тисячі разів. Взагалі виходить так, що краще розташовувати словники на найвищому рівні ієрархії. Це може потребувати деякої “інверсії адресації”; наприклад, не масив словників, а словник масивів.
-
Як вже писав вчора, з боку оптимізації памʼяті вибір між структурою та вказівником набирає новий сенс: бо дозволяє уникнути фрагментації. Наприклад, масив з 1000 структур буде одним блоком пам’яті: структури зберігатимуться послідовно. Масив з 1000 вказівників - 1001 блоками: вказівники будуть в масиві послідовно, а структури — кожна окремо.
-
Хоч рядки в Go є константами, але це ніяк не значить, що дві змінні-рядки з однаковим значенням зберігатимуться в памʼяті лише один раз. Так станеться тільки якщо ми призначимо одну змінну іншої. Це особливо стосується завантаження з JSON: якщо у вас рядок повторюється мільйон разів, кожний зберігатиметься окремо. Поки найкраще, що я можу тут придумати — це власний
Unmarshal
, який буде заміняти прочитане значення на глобальну константу. (Причому тоді зовсім не обовʼязково робити ту константу рядком.)