字符串如何存储在VBA字典结构中?

时间:2013-12-18 12:51:46

标签: excel vba dictionary

由于我目前正在玩大量的字符串(看看另一个问题:VBA memory size of Arrays and Arraylist)我使用脚本字典只是为了它具有的键控访问功能。 一切都看起来很好,除了它加载字符串有点慢,它使用了大量的内存。对于长度为128个字符的100,000个字符串的示例,任务管理器在sub的末尾显示大约295 MB,并且当设置Dictionary = Nothing时,Excel中剩余的差12 MB。即使考虑到内部Unicode转换字符串128 * 2 * 100,000也会产生25.6 MB!有人可以解释这个巨大的差异吗?

1 个答案:

答案 0 :(得分:5)

以下是我在Scripting.Dictionary上可以找到的所有信息:

编写Scripting.Dictionary的

According to Eric Lippert,“泛型字典的实际实现是一种可扩展的散列与链接算法,当表格过满时会重新散列。” (从上下文中可以清楚地看出他指的是Scripting.Dictionary)维基百科的article on Hash Tables是对所涉及概念的一个很好的介绍。 (Here是搜索Eric的博客上的Scripting.Dictionary,他偶尔会提到它)

基本上,您可以将哈希表视为内存中的大型数组。您必须提供密钥(通常是字符串),而不是直接通过索引存储字符串。密钥变为“散列”,即,将一组一致的算法步骤应用于密钥,以将其压缩为哈希表中0和当前最大索引之间的数字。该数字用作将字符串存储到哈希表中的索引。由于每次对键进行哈希处理时都会应用相同的步骤,因此每次都会生成相同的索引,这意味着如果您通过其键查找字符串,则无需像通常那样搜索数组。

散列函数(将键转换为索引到表中的那个)被设计为尽可能随机,但每隔一段时间两个键就可以缩小到相同的 index - 这称为碰撞。这是通过在链表中(或可能是更可搜索的结构)将字符串“链接”在一起来处理的。因此,假设您尝试使用密钥在哈希表中查找字符串。键是哈希的,你得到一个索引。查看该索引处的数组,如果没有添加具有该键的字符串,则它可以是空插槽,或者它可以是包含一个或多个字符串的链接列表,其键映射到数组中的该索引。

完成上述细节的全部原因是要指出哈希表必须大于它为保证效率而存储的内容的数量(有一些例外,请参阅Perfect Hash Function)。您在Hash Table中看到的大部分开销都是数组的空白部分,必须在那里使哈希表有效。

此外,调整哈希表的大小是一项昂贵的操作,因为必须将所有现有字符串重新分配到新位置,因此当哈希表的加载因子超过预定义阈值并且调整大小时,它可能会加倍大小,以避免不久再次这样做。

在每个数组位置保存字符串链的结构的实现也会对开销产生很大影响。

如果我发现其他任何内容,我会在此处添加...