performance - 当两个输入集之一是普通集时,zinterstore 会更快/更慢吗?

标签 performance redis

我知道我可以使用正常集作为参数( Redis: How to intersect a "normal" set with a sorted set? )来创建 zinterstore。这会影响性能吗?它会比仅使用 zset 更快/更慢吗?

最佳答案

根据sorted-set source code , ZINTERSTORE 会将集合视为分数为 1 的有序集合,函数名称为 zunionInterGenericCommand。

相交集将花费或多或少的时间,具体取决于此步骤中使用的排序算法,例如:

   /* sort sets from the smallest to largest, this will improve our
     * algorithm's performance */
    qsort(src,setnum,sizeof(zsetopsrc),zuiCompareByCardinality);

Set 和 Zset 的存储方式也存在差异,这会影响它们的读取方式。 Redis 将根据集合包含的元素数量来决定如何对(排序)集合进行编码。因此,迭代它们需要不同的工作。

但是,出于任何实际目的,我认为您最好的选择是使用 ZINTERSTORE,我将解释原因:我几乎看不出您在源代码中编写的任何内容会如何击败Redis 在做你想做的交集时的性能。

如果您关心的是性能,那么您就会过多关注细节。您的焦点应该放在操作的大 O 上,如命令 documentation 所示。 :

Time complexity: O(NK)+O(Mlog(M)) worst case with N being the smallest input sorted set, K being the number of input sorted sets and M being the number of elements in the resulting sorted set.

这告诉你的是: 1-较小集合的大小和您计划相交的集合的数量确定第一部分。因此,如果你知道你总是会相交 2 个集合,一组很小,另一组很大;那么你可以说第一部分是不变的。一个很好的例子就是将商店中所有可用产品的集合(其中分数是库存数量)与用户购物车中的一组已排序产品相交。

在这种情况下,您将只有 2 套,并且您会知道其中一套非常小。

2-结果排序集 M 的大小可能会导致很大的性能问题。但这里有一个技巧:当大的排序集太大时,它们会被编码为跳过列表。小型排序集将存储为 zip 列表,这可能会在大型排序集中造成重要影响。

但是,对于相交的情况,您知道结果集不能大于您提供的较小的集。对于并集,结果集将包含所有集中的所有元素;因此,需要更多地关注较大集合的大小,而不是最小集合的大小。

总之,(排序)集合的性能问题的答案是:它更多地取决于集合的大小,而不是实际数据类型。请考虑到,无论所有输入都是集合,结果数据结构都将是一个排序集合。因此,一个大的排序集将被存储(效率较低)作为跳过列表。

事先知道您计划相交的集合数(2、3,取决于用户输入?)以及较小集合的大小(10?数百?数千?)将使您比内部数据类型更好地了解。两种类型的相交算法相同。

关于performance - 当两个输入集之一是普通集时,zinterstore 会更快/更慢吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39468717/

相关文章:

Python redis rpop 是 resultng b'value' 列表结构

node.js - redis中循环保存数据的方法

java - "Can' t启动redis服务器”尝试在我的MacBook M1(Sonoma 14.0)上运行Spring Boot时出现异常

database - 中止 BGSAVE 已经在进行中

ruby-on-rails - Rails 应用程序中的慢动作:ActionDispatch::Routing::RouteSet#call

jQuery IE6 困境 : animate scrollLeft or left?

javascript - 从函数调用返回值时,最新的 JavaScript/ECMAScript 编译器是否会优化不必要的变量赋值?

c# - 设计一个可以直接处理 IL 的 CPU 有什么意义吗?

C++ - 执行速度测试的正确方法是什么?

redis - jedis 连接设置以实现高性能和可靠性