我一直在使用sinter来处理无序整数集的交集。有没有更快的交叉方式,因为我不会预先排序(或执行任何其他预处理)?
修改 找到一些信息[这里] [1]
EDIT2: 具体答案的赏金:比烧结更快的zinterstore?基准测试也很酷。
答案 0 :(得分:6)
在列表中,列表的大小具有复杂度O(N),其中N是最小集合的基数。
使用SET(SINTER / SINTERSTORE)如果有稀疏数据/应保持RAM低( O(N * M))并使用BITSET({{3} } / SETBIT)在所有其他情况下( O(N)。就像在您的编辑BITOP中一样。
Redis BIT密钥操作具有复杂度O(N),其中N是最小密钥的基数。并且bitops具有基于CPU缓存的最佳执行速度(查看bitops.c
源)。因此,如果您没有解析数据或者内存对您来说不重要,那么这可能是绝对的赢家(在Redis中info更多的字符串)。
不要使用ZSET(zinterstore)你是否有简单的整数列表并希望与它们相交。 Redis中的排序集是一种复杂的结构,其中密钥存储在ziplist
或skiplist
内部编码中。最后一个用于存储排序分数,但密钥存储在其他结构中。在ZSET交叉点的情况下,比较SET总是很复杂:
ZSET 交集: O(N * K)+ O(M * log(M))最坏情况,N是最小输入排序集,K是输入有序集的数量,M是结果有序集中的元素数。
SET 交集: O(N * M)最坏情况,其中N是最小集合的基数,M是集合数。实际上,理论上数学基础最小。
SET使用dict
/ intset
数据结构来存储数据,在您的情况下(无序整数集)将使用intset
。 Intset
Redis中最大的内存保存结构。并且与ziplist
(双重链表,here is)进行比较,获得最佳阅读速度。