内存效率:hashmap与数组



我正在考虑以下情况:我想计算字符串中字符的发生(例如,用于置换检查)。

一种方法是用256个整数分配一个数组(我认为字符是UTF-8),用零填充它,然后浏览字符串并递增数组位置上的整数达到字符的int价值。

但是,对于这种方法,即使分析的字符串非常短,您也必须每次分配256个数组(因此仅使用数组的一小部分)。

另一种方法是使用角色来整数空语张贴,并为每个遇到的char存储一个数字。这样,您只会有实际在字符串中的字符的键。

因为我对标签的理解是理论上的,我真的不知道它是如何在Java中实施的:我的问题是:两种方法中的哪种将更有效地有效?

编辑:

在讨论这个问题(谢谢您的回答)中,我确实意识到我对UTF-8的性质有一个非常模糊的理解。搜索后,我发现了我想分享的很棒的视频,以防有人遇到同样的问题。

当您假设字符串为UTF-8时,为什么选择256作为数组的长度。在UTF-8中,一个字符可以由多达4个字节组成,这意味着比仅256个字符。

无论如何:使用hashtable/hashmap需要一个巨大的内存开销。首先,您的所有字符和整数都需要包裹在对象(整数/字符)中。整数消耗大约3倍的内存。对于数组,由于优化Java在数组上执行的优化,差异可能更大(例如,Java堆栈仅在4个字节的倍数中起作用,而在数组中,Java允许较小的类型(例如Char),例如Char仅消耗2个字节)。

然后,标签本身会创建一个内存开销,因为它需要维护一个数组(通常不完全使用)和链接列表以维护所有生成相同哈希的对象。

此外,对于数组而言,访问时间将大大更快。您保存多个方法调用(添加,hashcode,Iterator等),并且在Java字节代码中存在许多OPCODE,以使使用数组更有效。

无论如何。您的问题是:

两种方法中的哪种将更有效?

可以肯定地说数组将更有效。

但是,您应该绝对确定您的要求是什么。您需要更多的内存效率吗?(如果您处理大量数据或使用慢速设备(移动设备?),可能是正确的)代码可读性有多重要?代码尺寸怎么样?重新求解性?

和IST 256真的是正确的大小?

而没有查看代码,我知道hashmap至少需要一个基本对象,每个哈希条目的标签阵列和各个对象。通常,int值必须作为整数对象存储,以便更多对象。假设您有30个独特的字符:

  • 基本对象的32个字节
  • 256个字节,用于最小尺寸的哈希表数组
  • 30个表条目中的每一个32个字节
  • 16个字节(如果高度优化)30个整数中的每个字节

32 256 960 480 = 1728字节。那是最少的,非自豪的实施。

256 int的数组将约为1056字节。

我将使用数组。从性能方面,您保证不断访问。比哈希桌能给您的东西更好。

,由于它也只使用恒定的内存量,因此我认为没有缺点。即使您只存储一些元素,HashMap也很可能需要更多的内存。

顺便说一句,内存足迹不应该是一个问题,因为只要您需要计算数据结构,就只需要数据结构即可。然后,它将是垃圾收集的。

这是事实。

  • HashMap在幕后使用数组。

因此,如果您实际上是通过在内存中找到连续的空间而受到限制的,那么Hashmap的好处只是数组可能较小。

  • HashMap是通用的,因此使用对象。

对象占用额外的空间。我记得,它通常是8或16个字节的最小值,具体取决于它是32位还是64位系统。这意味着即使字符串中的字符数量很少,哈希图也可能不会较小。Hashmap将需要每个条目的3个额外对象:Entry,A CharacterInteger。Hashmap还需要存储本地索引的int,而数组则不存储。

这还可以使用hashmap进行一些额外的计算。

我还会说,在这里您不必担心空间优化。无论哪种方式,内存足迹实际上都很小。

初始化代表char的int值的整数数组,例如F是102,这是其ASCII值

http://www.asciatible.com/

char c = 'f';
int x = (int)c;

如果您知道char的范围正在处理,则更容易。

对于每次发生char的情况,递增该数组中该字符的索引。如果您要排序但不会进行记忆密集型,则这种方法会很慢。

当您排序时,请注意丢失索引