计算每次获取哈希的字节数

问题描述 投票:0回答:1

我正在阅读 O'Reilly 的《美丽代码》第四章。本章的作者做了一个粗略的计算,但我没有遵循。

作者解释了如何创建一个哈希,其中键的主机名和值的时间戳和文章名称列表。比如,

{
"egspd42470.ask.com" : [1166406027, "2006/05/03/MARS-T-Shirt"],
"84.7.249.205" : [1166406040, "2003/03/27/Scanner"],
}

他指出有 2,345,571 个主机名、12,600,064 个提取实例,并且在创建哈希时“程序增长到占用了 1.56 GB 内存”。然后他声称,

“稍微计算一下,存储每个主机的信息大约需要 680 字节,或者以另一种方式切片数据,每次获取大约需要 126 字节”

  1. “每次获取的字节数”如何成为相关指标?哈希映射不是静态存储吗?也就是说,如果密钥是一个 8 字节字符串,那么每次获取的字节不总是 8 字节吗?

  2. 他如何获得每个主机 680 字节和每次获取 126 字节? 1.56 / 2,345,571 ~= 665 字节/主机,1.56 / 12.6 ~= 每次提取 0.123 字节,根据单位进行调整。然而,两者都不符合他给出的数字。使用提供的确切数字并对它们进行四舍五入,我无法生成给定的估计值。

以防万一,他正在分析的哈希值是用 Ruby 实现的。

hashmap estimation
1个回答
0
投票

“每次获取的字节数”如何成为相关指标?

“每次读取字节数”确实是一个非常不寻常的指标,从表面上看,它对程序员来说不太可能有任何用处,但也许可以用于营销(即对每次读取收费,这样有助于支付 RAM 费用)成本)。也就是说,由于我自己没有读过这本书,所以我不能排除他描述了一种场景,其中存在固有的获取操作,并且将一些数据添加到关联的值数组中,或者存在每次获取内存使用的其他方式.

哈希图不是静态存储吗?也就是说,如果密钥是 8 字节字符串,那么每次获取的字节不总是 8 字节吗?

哈希表的内存使用量不会仅仅因为您进行哈希查找而增加,如果这就是您所说的“静态”的意思。 (他们倾向于使用“动态分配”而不是“静态”内存,但这可能不是您所讨论的。)

也就是说,如果 key 是一个 8 字节的字符串,那么每次获取的字节不总是 8 字节吗?

再次强调,“每次读取的字节数”是一个愚蠢的指标。每次完成提取时,必须将正在查找的密钥与与该密钥散列到的存储桶关联的任何一个或多个密钥进行比较。因此,假设您获得一个 8 字节字符串键,然后对其进行散列(这涉及使用字符串内容进行一些计算),然后找到存储桶并迭代插入其中的任何条目:对于找到的每个条目,您可能首先进行比较哈希值(如果它们已保存在哈希表中),或者您可以直接比较字符串(可能从比较字符串长度开始,然后如果相同,则从一端扫描字符串,同时与另一个字符串)。但是,在耗尽可能已哈希到同一存储桶的其他字符串之前,您可能必须与多个字符串进行比较。因此,对于在获取过程中必须处理多少字节的数据,没有确切的答案。不过,考虑到哈希表的 O(1) 属性,它通常与字符串长度具有相同的数量级。

他如何获得每个主机 680 字节和每次获取 126 字节? 1.56 / 2,345,571 ~= 665 字节/主机,1.56 / 12.6 ~= 0.123 字节每次提取调整单位。然而,两者都不符合他给出的数字。使用提供的确切数字并对它们进行四舍五入,我无法生成给定的估计值。

我同意你的 665 是每个主机名的哈希表使用的上限,所以他的 680 是不可能的,因此是错误的。每个获取指标的可疑字节应约为 123.8 字节。也许当他使用实际值而不是已经四舍五入到 1.56G 时,“每次获取”指标接近 126 字节......无论如何都没有太大区别。

老实说,总的来说,如果您必须关心哈希表的内存使用情况,请填充您自己的数据并查看进程使用情况如何增长。对于不同的语言、数据类型、文本编码、哈希表实现以及编译语言 - 发布与调试模式和优化级别/标志,它会有点不同。

© www.soinside.com 2019 - 2024. All rights reserved.