ruby - Redis 和 Ruby 中的 ZRANGEBYSCORE

标签 ruby redis big-o benchmarking

我正在尝试用 Ruby 优化我的 Redis 代码中的 ZRANGEBYSCORE。

具体来说,Redis 网站 ( http://redis.io/commands/zrangebyscore ) 声明:

Time complexity: O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).

因此,正如我所读,只要我使用限制,无论限制设置为 48 还是 6,big(O) 都应该恒定为 O(log(N)。但是,我的基准测试似乎另有所指。

require 'redis'

def bench(descr)
    start = Time.now
    yield
    puts "#{descr} #{Time.now-start} seconds"
end

def with_pipelining_48
    id = 26053643
    @@redis.pipelined {
        1000.times {
            @@redis.zrevrangebyscore("key:#{id}", "+inf", "-inf", :limit => [0, 48],:with_scores => true)
        }
    }
end

def with_pipelining_24
    id = 26053643
    @@redis.pipelined {
        1000.times {
            @@redis.zrevrangebyscore("key:#{id}", "+inf", "-inf", :limit => [0, 24],:with_scores => true)
        }
    }
end

def with_pipelining_12
    id = 26053643
    @@redis.pipelined {
        1000.times {
            @@redis.zrevrangebyscore("key:#{id}", "+inf", "-inf", :limit => [0, 12],:with_scores => true)
        }
    }
end

def with_pipelining_6
    id = 26053643
    @@redis.pipelined {
        1000.times {
            @@redis.zrevrangebyscore("key:#{id}", "+inf", "-inf", :limit => [0, 6],:with_scores => true)
        }
    }
end

bench("with pipelining_48") {
    with_pipelining_48
}
bench("with pipelining_24") {
    with_pipelining_24
}
bench("with pipelining_12") {
    with_pipelining_12
}
bench("with pipelining_6") {
    with_pipelining_6
}

返回以下结果:

with pipelining_48 1.709097 seconds
with pipelining_24 0.930054 seconds
with pipelining_12 0.801045 seconds
with pipelining_6 0.633037 seconds

我的结果似乎与 Redis 文档不一致。有人可以阐明可能导致差异的原因吗?

最佳答案

因此,首先,对于真正的基准测试,您应该在剔除异常值后取平均值。所有这些操作之间的差异都以毫秒为单位,因此,如果您只是遇到一个微小的网络问题,或者您的盒子上发生了一些奇怪的事情,它就会把数字丢掉。如果这样做,您的数字可能看起来会有所不同。

其次,当您对 Redis 运行操作时,发生的不仅仅是操作成本。与 Redis 的连接需要连同其他相关的启动成本。数据也需要传输,而且会有网络来回。您所安排的时间不仅仅是运营成本,还有所有这些辅助成本。这些也将是非线性的,因为可以根据数据大小使用不同的格式来保存数据。总而言之,主要的一点是zrevrangebyscore是O(log(n)+m),但是操作中也有辅助成本,并且操作成本低(几乎总是Redis 的情况),这些成本使操作的实际成本相形见绌。这是好事。

关于ruby - Redis 和 Ruby 中的 ZRANGEBYSCORE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24397746/

相关文章:

mysql - rails : Database Seed

node.js - socket.io-redis 不断抛出 NOAUTH 错误

node.js - 如何为redis请求设置 Node 超时

spring-boot - 伪装客户端和 Redis

algorithm - 以下循环的运行时间

ruby-on-rails - github-pages 的 bundle 更新失败

ruby-on-rails - 如何使用 Rails 安装 Webpacker

ruby-on-rails - Ruby Rails %r 和 %w

algorithm - 以 θ(n) 复杂度对数组进行排序

python - 在列表中寻找下降。这可以在 O(log n) 中完成吗?