我正在考虑使用RocksDB或LevelDB来持久存储我的人脸识别软件数据。现在,我使用的是c ++向量而且它不是持久的,这意味着每次重新启动我的软件时,我都必须将数据重新加载到我的向量中。我的数据有大约100万个元素,每个元素是512个浮点数的向量。查询速度是最受关注的,理想情况下,当我使用索引查询时,我需要o(1)查询速度。根据我的研究,我无法真正找到RocksDB和LevelDB的这种保证。
我的问题是我是否值得投入使用RocksDB或LevelDB,还是比矢量慢?
答案 0 :(得分:0)
关于索引结构问题的简短回答是" no。" 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相比,在内存中搜索一个小树非常。搜索索引不太可能影响读取速度。
与此同时,使用数据库不太可能比上面的代码更容易编写,并且它几乎没有机会更快(尽管例如,可能可以提供比您的操作系统更有效的缓存,因此在某些情况下它会更快。)