在地图中存储大量字符串的内存效率最高的方法是什么?

时间:2016-06-15 14:00:57

标签: java string memory collections memory-optimization

我想在Map<String, MagicObject>中存储大量字符串,以便可以快速访问MagicObjects。这张地图有很多条目,内存正成为瓶颈。假设MagicObjects无法优化,我可以在这种情况下使用哪种最有效的地图类型?我目前正在使用以下内容:

gnu.trove.map.hash.TCustomHashMap<byte[], MagicObject>

3 个答案:

答案 0 :(得分:4)

如果您的密钥足够长并且有足够长的公共前缀,那么您可以使用trie(前缀树)数据结构来节省内存。 this question的答案指向trie的几个Java实现。

答案 1 :(得分:1)

要开放思绪,请先考虑Huffman coding来压缩字符串  放入地图,只要您的字符串是固定的(字符串的数量和内容不会改变)。

答案 2 :(得分:-1)

我对这个派对来说有点迟了但这个问题出现在一个相关的搜索中并激起了我的兴趣。我通常不回答Java问题。

  

这张地图有很多条目,内存正成为瓶颈。

我对此表示怀疑。

为了在内存中存储字符串成为瓶颈,你需要大量独特的字符串[1]。为了解决这个问题,我最近使用了一个1.8米的单词字典(1.8米独特的英文单词),并且在运行时它们占用了大约1.6MB的RAM。

如果您使用字典中的每个单词作为键,您仍然只能使用1.6MB的RAM [2]来存储密钥,因此内存不会成为您的瓶颈。

我怀疑你遇到的是字符串匹配的O(n ^ 2)性能。我的意思是,随着更多密钥的增加,性能会以指数方式减慢[3]。如果您使用字符串是键,这是不可避免的。

如果你想加快速度,可以将每个密钥存储到一个不存储重复项的哈希表中,并使用哈希键作为地图的键。

注意:

[1]我假设字符串都是唯一的,否则你不会尝试将它们用作地图的键。

[2]即使Java每个字符使用2个字节,它仍然只有3.2MB的内存,总数。

[3]如果您选择了错误的数据结构(例如不平衡的二叉树)来存储您的值,它会更慢。我不知道map如何在内部存储值,但是不平衡的二叉树将具有O(2 ^ n)性能 - 几乎是你能找到的最差性能。