第一次在PyPi上传开源工程,各种问题搞的相当坎坷,先贴个github地址
github: https://github.com/524243642/ratel
PyPi:https://pypi.org/project/ratel/
本工程参考redis的开源工程(redis源代码十分优秀)
编写这个库的缘由是我在编写一个工程化的策略的模块的时候碰到一个棘手的问题,先来描述一下我碰到的问题
数据结构需要满足的条件为
1.能够获取分数最小的对象,在此基础上进行update操作进行分数的更新(分数可能重复,key不重复)
2.能够根据key获取对象,满足一,定条件后进行update操作对象分数
3.根据key删除对象
以下介绍各种方案:
1)纯列表
根据key获取对象需要遍历搜索,时间复杂度为O(n)),获取分数最小的对象需要排序,时间复杂度为O(nlogn)
2)字典
根据key获取对象时间复杂度为O(1),获取分数最小的对象需要排序,时间复杂度为O(nlogn)
3)优先队列
优先队列可以满足分数可能重复,key不重复的场景,能够满足条件1,目前python内置priority queue无法满足条件2和条件3
4)PyPi跳表
https://pypi.org/project/python-skiplist/
目前这个实现底层采用c语言代码,比较高效
但是这个列表是根据key进行排序,如果把score作为key,则不支持重复分数插入,(对于这个问题,redis就做的比较全面,以很精简的结构支持很多业务型操作)
5)redis zset
能够支持各种复杂的业务操作,包括根据key查询操作能够维持在O(1)的复杂度,但是在PyPi上没有相应的实现
redis zset具体数据结构分析详见
https://blog.csdn.net/u012748735/article/details/82897479
6)python zset
楼主目前上传到PyPi上的redis zset的Python实现,集成了coverage和ci检测,目前能够稳定运行
api采用内置对象的原因是因为,分数可能会更改,方便对象的回溯行为
由于目前python list是链表的实现,为了增强性能,python zset 采用numpy array的内置对象来实现快速的下标访问 ,(2018-12-23)目前采用cython实现
经过benchmark实际测试,性能在数据量大的时候比较有优势
目前支持的api
ZsetObj Operations | Average Case |
---|---|
zadd | O(log N) |
zincrby | O(log N) |
zrem | O(log N) |
zscore | O(1) |
zcard | O(1) |
zrange | O(log N) |
zrevrange | O(log N) |
zfloor | O(log N) |
zlower | O(log N) |
zrange_by_score | O(log N) |
zrevrange_by_score | O(log N) |
如果有需要扩展的api,通过邮箱联系博主进行增强
借此来帮助有需要的朋友,由于是第一次搞这种工程,难免有什么不妥的地方,如果各位在使用过程中有什么疑问或者问题,欢迎大家批评指正(勇提pull request),大家共同进步
版本更新
2018-11-28 0.2.19 纯python实现版,insert 1w/0.5s
2018-12-04 0.3.3 cython实现,insert 10w/0.5s,性能提升一个数量级
2018-12-23 支持zfloor,zlower支持一致性hash所需要的查询方式
2019-01-23 接入shields.io
2019-04-25 支持zrange_by_score,zrevrange_by_score
博主邮箱:
[email protected]
附录
eq:c python api 和cython
https://www.2cto.com/kf/201606/517257.html
使用c python api写数据结构比较麻烦,需要关注引用计数,cython编写需要掌握cython优化语法,通过编写pyx,然后调用so
eq:c python各种架构
https://www.jianshu.com/p/fc5025094912