Вътрешно Redis съхранява низове по най-ефективния начин. Принудителното въвеждане на цели числа в низове с основа 10 всъщност ще използва повече памет.
Ето как Redis съхранява Strings -
- Цели числа по-малки от 10 000 се съхраняват в споделен пул памет и нямат допълнителни разходи за памет. Ако желаете, можете да увеличите това ограничение, като промените константата REDIS_SHARED_INTEGERS в redis.h и прекомпилирате Redis.
- Цели числа, по-големи от 10 000 и в обхвата на long, консумират 8 байта.
- Обикновените низове заемат len(низ) + 4 байта за дължина + 4 байта за маркиране на свободно пространство + 1 байт за нулев терминатор + 8 байта за режийни разходи на malloc.
В примера, който цитирахте, става въпрос за 8 байта за дълъг v/s 21 байта за низа.
РЕДАКТИРАНЕ:
Така че, ако имам набор от числа, всички по-малко от 10 000, как Redis съхранява моя набор?
Зависи колко елемента имате.
Ако имате по-малко от 512 елемента във вашия набор (вижте set-max-intset-entries
), тогава наборът ще бъде съхранен като IntSet. IntSet е прославено име за сортиран целочислен масив. Тъй като вашите числа са по-малки от 10 000, той ще използва 16 бита на елемент. Той е (почти) толкова ефективен от паметта, колкото C масив.
Ако имате повече от 512 елемента, наборът се превръща в HashTable. Всеки елемент в набора е обвит в структура, наречена robj
, който има режийни разходи от 16 байта. robj
структурата има указател към споделения пул от цели числа, така че не плащате нищо допълнително за самото цяло число. И накрая, robj
екземпляри се съхраняват в хеш-таблицата и хеш-таблицата има допълнителни разходи, които са пропорционални на размера на набора.
Ако се интересувате колко точно памет консумира даден елемент, стартирайте redis-rdb-tools на вашия набор от данни (отказ от отговорност:аз съм авторът на този инструмент). Или можете да прочетете изходния код за класа MemoryCallback, коментарите обясняват как е разположена паметта.