Optimize skiplist query efficiency by embedding the skiplist header#2867
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## unstable #2867 +/- ##
============================================
- Coverage 74.38% 74.23% -0.15%
============================================
Files 129 129
Lines 70972 70974 +2
============================================
- Hits 52791 52691 -100
- Misses 18181 18283 +102
🚀 New features to boost your workflow:
|
Signed-off-by: chzhoo <czawyx@163.com> Signed-off-by: GitHub <noreply@github.com>
Signed-off-by: chzhoo <czawyx@163.com> Signed-off-by: GitHub <noreply@github.com>
00c9a4b to
c2c63b9
Compare
ranshid
left a comment
There was a problem hiding this comment.
Nice!
I will do a deeper review, I just want to first eliminate concerns about potential future extensions of the skiplist metadata.
Signed-off-by: chzhoo <czawyx@163.com>
Signed-off-by: chzhoo <czawyx@163.com>
Signed-off-by: chzhoo <czawyx@163.com>
Signed-off-by: chzhoo <czawyx@163.com>
|
This looks good to me! I very much like the move towards making an interface (like for defrag.c) and keeping the implementation details more componentized. FYI, since a lot of skiplist work has been going on, I am currently working on a proof of concept for replacing skiplist with a B+ tree. My main goal is memory savings and my secondary goal is performance. I hope to have some real test numbers to back up my proposal in a few weeks. It's great that you're making it harder to show an improvement over skiplist though 😆 |
Signed-off-by: chzhoo <czawyx@163.com>
Signed-off-by: chzhoo <czawyx@163.com>
…alkey-io#2867) Embedding the skiplist header reduces memory jumps, thus optimizing sorted set query speed. ``` // Before typedef struct zskiplist { struct zskiplistNode *header, *tail; unsigned long length; int level; /* Height of the skiplist. */ } zskiplist; // After typedef struct zskiplist { unsigned long length; struct zskiplistNode *tail; /* Since the span at level 0 is always 1 or 0 , * this field is instead used for storing the height of the skiplist. */ struct zskiplistLevel { struct zskiplistNode *forward; unsigned long span; } level[ZSKIPLIST_MAXLEVEL]; } zskiplist; ``` --------- Signed-off-by: chzhoo <czawyx@163.com>
…alkey-io#2867) Embedding the skiplist header reduces memory jumps, thus optimizing sorted set query speed. ``` // Before typedef struct zskiplist { struct zskiplistNode *header, *tail; unsigned long length; int level; /* Height of the skiplist. */ } zskiplist; // After typedef struct zskiplist { unsigned long length; struct zskiplistNode *tail; /* Since the span at level 0 is always 1 or 0 , * this field is instead used for storing the height of the skiplist. */ struct zskiplistLevel { struct zskiplistNode *forward; unsigned long span; } level[ZSKIPLIST_MAXLEVEL]; } zskiplist; ``` --------- Signed-off-by: chzhoo <czawyx@163.com> Signed-off-by: Harkrishn Patro <bunty.hari@gmail.com>
Description
Embedding the skiplist header reduces memory jumps, thus optimizing sorted set query speed.
Benchmark
Step 1
Generate the test data using the following lua script and cli command
lua script
cli command
valkey-cli eval "$(cat load.lua)" 0 $ZSET_COUNTStep 2
Run benchmark 5 times through the following command and select the peak value as the result
valkey-benchmark -n 5000000 -r $ZSET_COUNT --threads 2 zrange zset:__rand_int__ 0 0Benchmark result
Benchmark Env
CPU: AMD EPYC 9K65 192-Core Processor * 8
OS: Ubuntu Server 24.04 LTS 64bit
Memory: 32GB
VM: Tencent Cloud | SA9.2XLARGE32