【问题标题】:File loaded to memory has much larger size than its disk size?!! Any way to compress?加载到内存的文件比它的磁盘大小大得多?!!有什么办法压缩吗?
【发布时间】:2012-02-24 19:48:30
【问题描述】:

我现在有一个棘手的问题。我有一个大字典文件要加载到我的程序中,它的格式基本上是:

word1 val1
word2 val2
word3 val3
...
...

这个文件有 170k 行,它在磁盘上的大小是 3.9MB(纯文本)。在我的实现中,我使用 boost::unordered_map (hashtable) 来存储这些数据以支持我的程序中的只读查找操作。

然而,在运行时加载到内存后,由于加载操作,内存使用量增加了20MB(我通过windows Task中的Private Working Set Size检查了这一点经理,也许这不是确定内存使用情况的正确方法?)。我知道哈希表中肯定有一些辅助数据结构来存储那些会增加内存使用的数据,但是我没想到内存大小是磁盘大小的5倍

这正常吗?由于我在 std 扩展库中尝试了另一个版本的 hashmap,并在其他一些内存中尝试了 Trie 结构,它们都没有在这个问题上带来显着的改进。

所以我想对这个问题进行一些空间优化。谁能提供一些提示或关键字来指导我提高空间使用率?

【问题讨论】:

  • 您可以使用压缩后缀树来压缩您的数据。但是你到底想用这些数据做什么?这些 val 有多大?
  • 在 Windows 上,20 MB 有问题吗?许多系统都有可用的 GB。
  • @BoPersson 是的,这是我现在需要解决的问题。

标签: c++ memory hashtable


【解决方案1】:

哈希映射数据结构分配的内存比它一次使用的要多得多。这是为了便于快速插入和移除。当哈希表达到一定容量(实现定义,但它是一个像 50% 已满、70% 已满、90% 已满等的数字)时,它将重新分配更多内存并复制所有内容。关键是它分配的内存比使用的多。

此外,您看到的程序使用的 20 MB 是您的程序正在使用的所有内存的大小,而不仅仅是一个哈希映射。

此外,如果您使用std::string 或等效结构来存储值,则您已经创建了从文件中获取的一半数据的副本。您将在读取文件的缓冲区中有一个副本,然后在哈希表中的strings 中有另一个副本。

【讨论】:

  • 是的,20MB是增量值,肯定是加载操作造成的。
  • @JXITC std::map(还有boost::map?我不知道,我不使用boost)实现为树形结构,也许你可以试试。它不会分配比它使用的更多的内存。
【解决方案2】:

如果您的字符串的最大大小相当小,您可以将它们存储在一个大字符数组中并使用二进制搜索进行查找(当然是在对它们进行排序之后)。

【讨论】:

    猜你喜欢
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 2020-04-12
    • 2019-08-21
    • 2012-07-12
    相关资源
    最近更新 更多