预灰化键以节省内存。
prehashed的Python项目详细描述
预灰化
一种python字典,在插入dict之前对键进行哈希运算。当字典的键相当大(例如长刺)时,这会节省大量内存。
关键是我们可以廉价地存储非常大(长字符串)的密钥例如,当将文档存储在标记化的dailymail数据集中时,密钥占用1.018gb,而此实现占用10.53mb。使用内置的hash
函数可以节省少量空间(7.79mb对10.53mb),但由于python在运行过程中更改种子,因此无法在运行过程中共享此结果
碰撞
显然,我们想知道发生哈希冲突的概率是多少?。我们可以通过反问来解决这个问题。所有密钥都是唯一的概率是多少?一旦我们有了这个,我们就可以用1减去这个来回答原来的问题
给定n个可能的散列值(2 ** 160
对于sha1),我们知道第一个散列是唯一的,然后对于第二个散列,我们知道可以使用并且仍然是唯一的N - 1
散列,这意味着我们的概率是N - 1 / N
。这种情况会持续到N - 2, 3
等。因此,如果我们对k
键进行散列,我们可以发现它们在PI i=1 -> k-1 (N - i) / N
中都是唯一的概率。这可以近似为。这可以用(k*(k 1)/(2×n))近似于小k,因为^ {CD9}},当n为2*160时,大多数k是小的。
图表
总而言之,这里有一张表,上面列出了一些钥匙相撞的可能性。
k | Odds |
---|---|
^{ | ^{ |
^{ | ^{ |
^{ | ^{ |
^{ | ^{ |
^{ | ^{ |
因此,除非您计划使用put171,000,000,000,000,000,000,000
键,否则如果您的代码有错误,人们将死亡,我不会担心冲突。
钥匙碰撞的可能性很小当这种情况发生时,本词典无法检测到,因此这些键将相互覆盖这是如此罕见,以至于git也没有一个缓解策略
虽然冲突是非常罕见的,如果你担心的话,我建议你所有的值都是相同的类型,这样你就不会期望字符串,如果发生冲突,在极不可能的情况下,会得到一个in t。
如果您仍然害怕冲突,还有一个函数initial_add(k, v)
,它将修改您的密钥,直到没有冲突为止,将其添加到字典中,并返回要使用的新密钥。你需要保留这个密钥,以便稍后获取值,这样就打破了这个dict的要点,你可以在这里扔掉你的密钥。