繁体   English   中英

BST还是哈希表?

[英]BST or Hash Table?

我有大型文本文件,需要执行各种操作,主要涉及逐行验证。 数据通常具有销售/交易性质,因此往往包含跨行的大量冗余信息,例如客户名称。 迭代和操作这些数据已经成为一项常见的任务,我正在用C语言编写一个库,我希望将其作为Python模块提供。

在一次测试中,我发现在130万列值中,只有约300,000个是唯一的。 内存开销是一个问题,因为我们基于Python的Web应用程序可以处理大型数据集的同时请求。

我的第一次尝试是读入文件并将每个列值插入二叉搜索树。 如果之前从未见过该值,则分配内存来存储字符串,否则返回指向该值的现有存储的指针。 这适用于~100,000行的数据集。 更大,一切都停止了,内存消耗急剧上升。 我假设树中所有节点指针的开销没有帮助,并且使用strcmp进行二进制搜索变得非常痛苦。

这种令人不满意的表现让我相信我应该投资使用哈希表。 然而,这提出了另一点 - 我不知道有多少记录。 它可能是10或一千万。 如何在时间/空间之间取得适当的平衡,以防止反复调整哈希表的大小?

在这种情况下,最好的数据结构候选者是什么?

感谢您的时间。

除非您要求表中的每个插入都占用相同的时间,否则不需要考虑哈希表的大小调整。 只要您始终将哈希表大小扩展一个常数因子(例如,总是将大小增加50%),添加额外元素的计算成本就会分摊O(1) 这意味着n插入操作(当n很大时)将占用与n成比例的时间量 - 但是,每次插入的实际时间可能会有很大差异(实际上,其中一次插入将非常慢,而其他插入将会很慢)非常快,但所有操作的平均值都很小)。 这样做的原因是当你插入一个额外的元素来强制表格从1000000到1500000元素扩展时,那个插入将花费很多时间,但是现在你需要在自己需要时自己购买500000个非常快的插入再次调整大小。 简而言之,我肯定会去哈希表。

您需要使用哈希表的增量大小调整 在我当前的项目中,我会跟踪每个存储桶中使用的哈希密钥大小,如果该大小低于表的当前密钥大小,那么我会在插入或查找上重新插入该存储桶。 在调整散列表的大小时,密钥大小加倍(向密钥添加一个额外的位),在所有新的桶中,我只需将指针添加回现有表中的相应存储桶。 因此,如果n是散列桶的数量,则散列扩展代码如下所示:

n=n*2;
bucket=realloc(bucket, sizeof(bucket)*n);
for (i=0,j=n/2; j<n; i++,j++) {
  bucket[j]=bucket[i];
}

C中的库我希望作为Python模块提供

Python已经内置了非常高效的精细调整哈希表。我强烈建议你先让你的库/模块使用Python。 然后检查速度。 如果这还不够快,可以通过使用Cython对其进行分析并删除您找到的任何减速带。

设置代码:

shared_table = {}
string_sharer = shared_table.setdefault

scrunching每个输入行:

for i, field in enumerate(fields):
    fields[i] = string_sharer(field, field)

您当然可以在检查每个列之后找到某些列不能很好地压缩并且应该从“scrunching”中排除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM