繁体   English   中英

Python的字典哈希数据结构

[英]Python's underlying hash data structure for dictionaries

我正在构建一个非常大的字典,我正在执行许多检查以查看密钥是否在结构中,然后添加它是否唯一或递增计数器(如果它是相同的)。

Python使用哈希数据结构来存储字典(不要与加密哈希函数混淆)。 查找是O(1),但如果哈希表已满,则必须重新进行,这非常昂贵。

我的问题是,我会更好地使用AVL二进制搜索树还是哈希表足够好?

唯一可以肯定的方法是实现和检查,但我的猜测是字典会更快,因为二进制搜索树花费了O(log(n))进行查找和插入,我认为除了在最不重要的情况下(例如大规模哈希冲突),哈希表的O(1)查找将超过偶尔的大小调整。

如果你看一下Python字典的实现 ,你会看到:

  1. 一个字典以8个条目开始( PyDict_MINSIZE );
  2. 一个包含50,000或更少条目的字典,当它增长时,它的大小是四倍;
  3. 超过50,000个词条的词典在增长时会增加一倍;
  4. 键哈希缓存在字典中,因此在调整字典大小时不会重新计算它们。

(“ 优化字典的注意事项 ”也值得一读。)

因此,如果您的词典有1,000,000个条目,我相信它将被调整大小十一次(8→32→128→512→2048→8192→32768→131072→262144→524288→1048576→2097152),额外插入成本为2,009,768调整大小。 这似乎远远低于将1,000,000次插入到AVL树中所涉及的所有重新平衡的成本。

商品与独特商品的比例是多少? 预期的独特商品数量是多少?

如果一个哈希桶填充,那么扩展应该只是一些内存重新分配,而不是重新分配。

测试计数字典应该非常快速和容易。

另请注意自python 2.7以来可用的计数器类http://docs.python.org/library/collections.html#counter-objects http://svn.python.org/view?view=rev&revision=68559

Python词典经过高度优化。 Python进行了各种特殊情况的优化,Python开发人员在CPython字典实现中提供了这些优化。

  1. 在CPython中,所有PyDictObject都针对仅包含字符串键的字典进行了优化。
  2. Python的字典努力永远不会超过2 / 3rds。

美丽的代码 ”一书讨论了这一切。

第十八章是Python的字典实现:由Adrew Kuchling为所有人提供的一切

使用它比尝试实现手工制作的自定义实现要好得多,后者必须将所有这些优化复制到任何接近主要CPython字典查找实现的地方。

您必须在C中实现自己的数据结构才能有合理的机会击败内置结构。

此外,您可以通过使用get避免一些开销,避免两次查找现有元素。 或者collections.Counter,如果你使用python 2.7+。

def increment(map, key):
    map[key] = map.get(key,0)+1

使用dict是O(1)。 随着字典的增长,有时需要重新分配,但这是摊销的O(1)

如果你的其他算法是O(log n),那么随着数据集变大,简单的dict将始终击败它。

如果你使用任何类型的树,我会期望在那里有一个O(log n)组件。

哈希表不仅足够好,而且更好

暂无
暂无

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

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