【问题标题】:Redis: Is ZADD better than O(logN) when the inserted element is at the beginning or end?Redis:当插入元素位于开头或结尾时,ZADD 是否优于 O(logN)?
【发布时间】:2011-10-31 17:11:36
【问题描述】:

ZADD 的 redis documentation 声明操作为 O(log N)。

但是,当插入的元素位于排序顺序的开头或结尾时,有人知道 ZADD 是否比 O(log N) 更好吗?

例如对于某些实现,这可能是 O(1)。

具体来说,redis tutorial 声明:

排序集是通过一个双端口数据结构实现的,其中包含 跳过列表和哈希表,所以每次我们添加一个元素 Redis 执行 O(log(N)) 操作。

修改跳过列表以支持在开头和结尾插入 O(k) 似乎是合理的,其中 k 是跳过列表的最大级别。

【问题讨论】:

    标签: redis sortedset skip-lists


    【解决方案1】:

    我在 Redis 网站上交叉发布了这个问题,Pieter Noordhuis 在那里提供了一个答案,我在这里交叉发布:


    没错。排序集依赖于 RNG 来确定每个节点的级别数(它是一种概率数据结构)。在跳过列表的开头插入/删除一个元素可能是 O(1),而理论上最坏情况的性能是 O(N)(每个节点具有相同的级别)。但是,考虑到节点之间的级别分布,摊销时间复杂度为 O(log N)。

    【讨论】:

    • 所以...答案是只要你在列表的头部插入你得到 O(1)?
    【解决方案2】:

    k和log(N)之间有关系吗?如果它们通过恒定因素相关,那么您实际上并没有改变任何东西。 (我不知道这种关系是否存在,但鉴于该主题上的wikipedia page 显然在层构造中具有这种关系,它看起来非常合理。OTOH,该页面没有链接到证明,我没有感觉现在是手工推导出来的,所以这只能是推测。)

    此外,总体而言,算法整体为 O(log N) 的事实并不能阻止特定特殊情况变得更好(例如,O(1))。

    【讨论】:

    • 我还发现有趣的是,跳过列表可能存在内存局部性问题(根据resnet.uoregon.edu/~gurney_j/jmpc/skiplist.html)。表明您应该始终衡量,而不是猜测。
    • 从那以后已经过去了很长时间,但是我发现这个问题真的很有趣,如果我想将一个现有的排序集插入到 redis 中,它是排序的,知道它以哪种方式可能会很有趣最好发送命令:反向,直接,好像我在构建一个二叉树......?
    猜你喜欢
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    相关资源
    最近更新 更多