1

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

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

4

1 回答 1

1

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

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

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

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 相比,在内存中搜索一棵小树也非常快。搜索索引不太可能显着影响读取速度。

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

于 2017-10-25T14:13:26.890 回答