【发布时间】:2019-07-07 19:35:05
【问题描述】:
我正在寻找有关如何最好地实现我的代码以满足以下要求的建议。在执行我的 c++ 代码期间,我经常需要访问存储在字典中的数据,而字典本身存储在文本文件中。该字典包含 1 亿个条目,并且在任何时间点,我的代码都会查询与这 1 亿个条目中的某个特定条目相对应的数据。进行这些查询没有特定的模式,而且在程序执行的生命周期内,并非字典中的所有条目都被查询。此外,字典在程序的生命周期内将保持不变。每个条目对应的数据并非都是相同的长度。我的字典的文件大小约为 24 GB,而我只有 16 GB 的 RAM 内存。我需要我的应用程序非常快,所以我想知道如何最好地实现这样的系统,以便最大限度地减少读取访问时间。
我也是创建字典的人,所以我可以灵活地将我的字典分成几个较小的卷。在考虑我能做什么的同时,我想出了以下几点,但不确定是否好。
- 如果我从文件开头存储字典中每个条目的行偏移量,然后读取相应条目的数据,我可以直接跳转到相应的偏移量。有没有办法使用 say ifstream 来做到这一点,而无需遍历所有行直到偏移线?在网上快速搜索似乎表明至少使用 ifstream 是不可能的,还有其他方法可以做到吗?
- 另一个极端的想法是为字典中的每个条目创建一个文件,这样我就有 1 亿个文件。这种方法的明显缺点是打开和关闭文件流的开销。
总的来说,我不相信我想到的任何一种方法都是好的,所以我想要一些建议。
【问题讨论】:
-
您可以考虑使用内存映射文件 - boost 具有多平台实现。至于性能 - 始终配置您的解决方案,
-
实现 trie 可能会减少内存占用。减少将取决于有多少单词以相同的前缀开头。对于完整的内存解决方案而言,这可能会或可能不会足够减少。
-
这听起来像是数据库的工作。有什么理由不使用?
-
@marcinj 谢谢你的建议。我想知道 Igor 建议的内存映射和 seekg 调用之间的权衡是什么。快速搜索似乎向我暗示内存映射在内部使用 seekg 调用。但是,在 seekg 上使用内存映射有什么方便吗?如果您认为这可以保证关于堆栈交换的单独问题,我可以创建一个。
标签: c++ file c++11 file-access