7

在我们的应用程序中,我们使用std::map存储(键、值)数据并使用序列化将数据存储在磁盘上。通过这种方法,我们发现磁盘 I/O 是性能瓶颈,使用 key 查找值并不是很快。

我遇到了 LevelDB 并考虑使用它。但我有一些问题。

  1. LevelDB 的文档说它是为 (string, string) 键值对制作的。这是否意味着我不能用于自定义键值对?
  2. 似乎std::map和 LevelDB 之间的区别在于 LevelDB 是持久的并且std::map在内存中工作。那么这是否意味着磁盘 I/O 瓶颈对于 levelDB 来说会更成问题。

更具体地说,有人可以解释一下 LevelDB 是否是更好的选择std::map吗?

PS:我尝试使用hash_maps 但它似乎比std::map

4

2 回答 2

9

LevelDB 只是做 std::map 以外的事情。

你真的是说你想要 std::map 的(高性能)持久性吗?

  • 使用自定义分配器查看 std::map 。从内存映射区域分配条目并使用 fsync 确保信息在关键时刻及时到达磁盘。

  • 也许将它与 EASTL 结合起来(它拥有更快的 std::map 并通过自定义分配器蓬勃发展 - 事实上它们没有默认分配器)

  • 看看调整你的 hash_map (std::unorderded_map); 如果 hash_maps 较慢,您应该查看 (a) loadfactor (b) 哈希函数调整

  • 最后但同样重要的是:评估使用 Boost Serialization 对地图进行二进制序列化(无论您选择什么实现)。以我的经验,提升序列化性能是最重要的。

于 2011-10-18T10:12:03.800 回答
2

你现在做的是这样的:

假设您在一个文件中有 1000000 条记录。您将整个文件读入 std::map,这需要大约 1000000 次操作。您使用 find/insert 来定位和/或插入元素,这需要对数时间(大约 20 次比较)。现在您再次保存整个文件,将所有这 1000000 条记录传输回文件。

问题是使用 std::map 对您毫无益处。std::map 为您提供快速的搜索时间(对数),但每次查找都初始化和序列化整个地图会抵消它的好处。

您需要的是重新设计您的程序,以便您将在启动时加载一次地图并在终止时将其序列化一次。或者,也许如果您需要数据库语义,请选择真正的数据库实现。我建议使用 SQLite,尽管 LevelDB 可能对你也一样好。

于 2011-10-18T10:16:19.927 回答