使用c++向量按索引查询是否比RocksDB或LevelDB中按键(索引)查询快

Is querying by index using c++ vector faster than querying by key(index) in RocksDB or LevelDB?

本文关键字:查询 索引 LevelDB 向量 c++ 是否 使用 RocksDB      更新时间:2023-10-16

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

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

关于索引结构的问题的简短答案是"否"。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不太可能比上面的代码更容易编写,而且几乎不可能更快(尽管可能它可以提供比操作系统更有效的缓存,因此在某些情况下会更快)。