【问题标题】:Is querying by index using c++ vector faster than querying by key(index) in RocksDB or LevelDB?在 RocksDB 或 LevelDB 中,使用 C++ 向量通过索引查询是否比通过键(索引)查询更快?
【发布时间】:2017-10-25 13:57:14
【问题描述】:

我正在考虑使用 RocksDB 或 LevelDB 为我的面部识别软件持久存储我的数据。现在,我正在使用一个 c++ 向量,它不是持久的,这意味着每次我重新启动我的软件时,我都必须将数据重新加载到我的向量中。我的数据有大约 100 万个元素,每个元素都是 512 个浮点数的向量。查询速度是最受关注的问题,理想情况下,当我使用索引进行查询时,我需要 o(1) 的查询速度。根据我的研究,我真的无法为 RocksDB 和 LevelDB 找到这样的保证。

我的问题是值得投入使用 RocksDB 或 LevelDB 还是它们比向量慢?

【问题讨论】:

  • 唯一的答案是:基准测试。
  • @VittorioRomeo 我只是在问岩石和水平是否总是较慢,或者是否会有更快的情况?如果它们总是较慢,那么基准测试毫无意义。
  • 慢一点 什么?内存直接访问?是的。比管理自己的文件和索引?也许。比一般的SQL数据库?可能不是。对于要“慢”一些的东西,你需要一些可以比较的东西。这就是您进行基准测试的原因。
  • @Someprogrammerdude 我写了向量(c++ stl向量)
  • 所以你有一个向量的向量?你如何找到正确的子向量?你有索引到向量的索引吗?那么这就是你将要获得的速度。如果您有内存将所有数据存储在内存中,那么只需对向量和索引进行一些简单的序列化即可。启动时加载,关闭时保存(或更改)。

标签: c++ vector leveldb rocksdb


【解决方案1】:

关于索引结构的问题的简短回答是“否”。 RocksDB 和 LevelDB 对其索引使用树结构(准确地说是日志结构的合并树),这转换为 O(log N) 查询。

鉴于您有固定数量的固定大小元素,您可以很容易地自行获得 O(1)“查询”。

只需将数据存储在二进制文件中即可。您可以使用istream::seekg 寻找合适的点,然后使用istream::read 读取512 个浮点数。

struct record { 
    float data[512];
};

std::istream &read_record(istream &is, size_t record_number, record &r) {
    auto read_start = record_number * sizeof(r);
    is.seekg(read_start);
    is.read(reinterpret_cast<char *>(r), sizeof(r));
}

但是,这是否真的提供了性能改进可能会有疑问。特别是,如果只有一百万个元素,二叉树的深度只有 20 左右。多路树会更浅。对于这么小的大小,很可能整个索引将一直在内存中,并且与即使是最微不足道的磁盘 I/O 相比,在内存中搜索一棵小树也非常快。搜索索引不太可能显着影响读取速度。

同时,使用 DB 不太可能比上面的代码更容易编写,而且几乎不可能更快(尽管 可能例如,它可以提供比您的操作系统更有效的缓存,因此在某些情况下它会更快)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 2012-09-26
    • 1970-01-01
    • 2017-09-12
    • 2013-08-23
    • 2020-04-28
    • 2010-09-12
    相关资源
    最近更新 更多