设置vs DAWG以检查Python中字典的成员身份

时间:2013-02-19 09:15:43

标签: python dictionary set hashset dawg

我需要能够快速检查给定的单词是否在我的词典中(英语单词列表)。我只关心检查成员资格的速度(不添加或删除元素),内存使用并不是真正的问题。

最初我使用的是这样的一套:

words = set(x.strip().lower() for x in open("/usr/share/dict/words").readlines())
if(word in words):
    ...

我的节目大约花了4s在测试输入上运行。然后,我试图通过使用DAWG(http://pypi.python.org/pypi/pyDAWG)来优化事物,而不是通过预先计算DAWG并对其进行酸洗:

words = pickle.load(open('wordlistDAWG.pyd'))
if(words.word2index(word) is not None):
    ...

在相同的测试输入上,程序然后需要大约40秒才能运行(包括几秒钟来加载我不关心的DAWG)。我希望使用DAWG会让事情变得更快!

也许我错过了一些关于python如何散列事物的理解 - 一套已经是最好的我会得到(O(1)会员资格测试?)而不是DAWG或Trie? DAWG是否会节省内存而不是计算?

非常感谢!

2 个答案:

答案 0 :(得分:1)

我认为如果将DAWG用作设备替代品,DAWG不会为您节省CPU周期。

关于设置大小,设置查找是O(1),关于DAWG项目计数,DAWG查找也是O(1)。 DAWG查找是关于查找密钥长度的O(N)(当DAWG中的密钥 时,检查密钥是否在DAWG中需要len(密钥)步骤)。设置查找也是关于密钥长度的O(N)(因为必须计算密钥的哈希值)。所以这归结为实现,

  • 散列图通常比其他数据结构(包括DAWG和Tries)更快;
  • Python集优化得很好;内置类型的哈希计算也得到优化; CPython中的sets / dicts具有unicode密钥的专用代码路径。
当项目不在DAWG中时,DAWG可能有优势,因为它需要少于len(关键)步骤来检查这一点,并且总是需要计算哈希len(键)步骤(好吧,如果没有缓存哈希值) )。但即使在这种情况下也难以击败内置套装。

一个无耻的插件 - 你也可以尝试https://pypi.python.org/pypi/DAWG - 但__contains__仍然比dict慢2倍。

顺便说一下,word2index的pyDAWG Python版本在内部执行许多dict查找,因此它不能比单个set查找更快。

答案 1 :(得分:0)

您通过调用word2index来使用完美的哈希功能,这听起来就像您不需要的那样。为什么不使用exists