为什么hash数据结构的底层,使用skiplist比直接使用hash会更节省内存呢?

  • 作者: 凯哥Java(公众号:凯哥Java)
  • 面试其他
  • 时间:2023-07-27 13:36
  • 2009人已阅读
简介 问题:1.为什么hash数据结构的底层,使用skiplist比直接使用hash会更节省内存呢?2.为什么要强调,在hash保存1000条数据以内时,底层使用skiplist呢?skiplist是在数据量较大的场景下,查询性能有明显优势吧,数据量越多,查询性能的提高越明显吧,这和存储有什么关系?为什么能节约内存?答:1.http://zhangtielei.com/posts/blog-redis-

🔔🔔好消息!好消息!🔔🔔

 如果您需要注册ChatGPT,想要升级ChatGPT4。凯哥可以代注册ChatGPT账号代升级ChatGPT4

有需要的朋友👉:微信号 kaigejava2022

问题:

1. 为什么hash数据结构的底层,使用skiplist比直接使用hash会更节省内存呢?

2. 为什么要强调,在hash保存1000条数据以内时,底层使用skiplist呢?

skiplist是在数据量较大的场景下,查询性能有明显优势吧,数据量越多,查询性能的提高越明显吧,这和存储有什么关系?为什么能节约内存?


答:1.http://zhangtielei.com/posts/blog-redis-skiplist.html

从内存占用上来比较,跳表比平衡树更灵活一些。

平衡树每个节点包含 2 个指针(分别指向左右子树),而跳表每个节点包含的指针数目平均为 1/(1-p),具体取决于参数 p 的大小。如果像 Redis里的实现一样,取 p=1/4,那么平均每个节点包含 1.33 个指针。

举个例子,下图有个 3 层级的跳表。

如果要查找「元素:abcd,权重:4」的节点,查找的过程是这样的:

先从头节点的最高层开始,L2 指向了「元素:abc,权重:3」节点,这个节点的权重比要查找节点的小,所以要访问该层上的下一个节点;

但是该层的下一个节点是空节点( leve[2]指向的是空节点),于是就会跳到「元素:abc,权重:3」节点的下一层去找,也就是 leve[1];

「元素:abc,权重:3」节点的 leve[1] 的下一个指针指向了「元素:abcde,权重:4」的节点,然后将其和要查找的节点比较。虽然「元素:abcde,权重:4」的节点的权重和要查找的权重相同,但是当前节点的 SDS 类型数据「大于」要查找的数据,所以会继续跳到「元素:abc,权重:3」节点的下一层去找,也就是 leve[0];

「元素:abc,权重:3」节点的 leve[0] 的下一个指针指向了「元素:abcd,权重:4」的节点,该节点正是要查找的节点,查询结束。

2.Hash 类型的底层数据结构是由压缩列表或哈希表实现的:

如果哈希类型元素个数小于 512 个(默认值,可由 hash-max-ziplist-entries 配置),所有值小于 64 字节(默认值,可由 hash-max-ziplist-value 配置)的话,Redis 会使用压缩列表作为 Hash 类型的底层数据结构;

如果哈希类型元素不满足上面条件,Redis 会使用哈希表作为 Hash 类型的 底层数据结构。


TopTop