游戏排行榜最优算法-字典树。与超快速跳表、redis跳表性能对比。

如果使用数据库,毫无疑问redis的有序集合(基于跳表)是最简单的
一般来讲很多文章也会推荐跳表skiplist
但是由于战力可转化为整数数值存储,论本地内存计算的数据结构,当属字典树最优

标准树容器都不支持容器内节点的字典序的距离差计算,但其实自己改造树是可以的实现的:每个分支记录分支下元素总数,每当有元素插入删除时,更新其所有祖先上的数量记录,用时O(层数)=O(log(N))

(4、8、16叉……)字典树,可以通过两个键值的异或运算快速找到最小公共父节点,层内定位是随机访问,且无需遍历比较直接用位运算定位节点,局部内存缓存效果超级好,数量加减都在树结构上完成。对比基于对比和概率的跳表来说各方面都优秀的多。

实测百万数据, 32叉字典树 对比高度优化的跳表,根据键值查找对象的性能快25倍,插入和rank性能都快约5~7倍(注意插入时内存申请的耗时已经达到不可忽视的程度)。



104万个数据(数值范围0~104万),操作104万次,相同release编译,每组测试交叉并在之间清除cpu内存缓存
Redis zsortedset源码抽取版(保留数据结构不变,脱离原工作环境,轻度改为模板类)
高度优化的跳表(估计理论极限性能85%+以上,比git上前4的skiplist实现快40%到150%,在含rank的完善实现中估计排行第一) ,
和32叉字典树对比:

redis sortedset
源码抽取版
double键
超快速跳表(15层)
支持重复键
元素总量超(2^层数)时自适应调整概率
元素存储于对应节点
int键(比double键快5%)
32叉字典树
(含排位功能,半支持重复键值)
int键(不支持其他类型)
随机插入2434ms827ms
234ms(稳定排序(严格要求按顺序插入时)+最佳建表)
171ms(不稳定排序(不要求同键顺序时)+最佳建表)
312ms(分16组不稳定排序+并集)
77ms(从有序数据源最佳建表=创建跳表副本)
140ms(32个小元素集成至底层节点)
218ms(为每个元素分配空间)
随机顺序 查找>=key的第一个对象2511ms890ms
390ms(最佳表)
47ms
值查排位2589ms890ms(与链表头部距离)
406ms(最佳表)
203ms(排位)
390ms(随机两键值距离算法)
排位查值343ms156ms
46ms(最佳表)
78ms
随机删除2153ms702ms(N次删除,每次删除键对应的第一个值)
818ms(N次删除,每次删除键对应的全部值(测试集只对应一个值))
593ms(最佳表 删除键第一个)
421ms(随机顺序删除N/2次,每次正好能删除两个值)
141ms(小类型集成)
171ms(为每个元素new)

new int {i} 104万次 耗时41ms
std哈希表 插入{i,i} 104万次 234ms,1677万次5320ms。

1677万个数据(数值范围0~1677万),操作1677万次。(16倍数据量和16倍操作)
括号内的倍率指与104万测试相比。

redis源码抽取版超快速跳表24层32叉字典树
插入75099ms28033ms(元素存储于链表节点)(28.19倍)
6193ms(稳定排序+最佳建表)
5288ms(分16组不稳定排序+并集)
2792ms(不稳定排序+最佳建表)
1170ms(从有序数据源最佳建表=创建跳表副本)
4820ms(32个小元素集成至底层节点) (34.42倍)
6100ms(为每个元素分配空间) (27.98倍)
查找>=key的第一个对象76591ms29625ms (30.03倍)
12995ms(最佳表)
1607ms (34.19倍)
值查排位81589ms30171ms(与链表头部距离) (33.01倍)
13495ms(最佳表)
5553ms(排位) (27.35倍)
10655ms(随机两键后算距离) (27.32倍)
排位查值7004ms3027ms(17.70倍)
1014ms(最佳表)
1513ms
删除73024ms28969ms(随机顺序查找键的第一个并删除)(35.72倍)5024ms(小类型集成) (35.63倍)
5679ms(为每个元素new) (33.2105倍)

1677万元素乱序,每次取104万排序后再合并到跳表中,16次,共计 5288ms。
不含排序的每次合并104万有序数据耗时(ms):
95,129,147,155,184,210,217,241,267,261,274,294,305,312,338,333

超快速跳表提供了 修改方面:更新key而不析构value;查询方面:排位(下标)→键值对,键/迭代器→排位(下标)这两个std::map不支持的功能。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值