儘管Jon Skeet的回答爲小投資節省了很多錢,但我認爲你可以做得更好。既然你的數字是相當均勻分佈的,你可以使用內插搜索來更快的查找(大概O(log log N)而不是O(log N))。對於一百萬個項目,您大概可以計劃大約4個比較,而不是大約20個。
如果您想再做一點工作以將內存(大致)再次削減一半,則可以將其構建爲兩個級查找表,基本上是一種簡單版本的trie。
你會打破你的(大概)32位整數分成兩個16位部分。您將使用前16位作爲查找表第一級的索引。在這個級別上,你會有65536個指針,每個可能的16位值用於你的整數部分。那會帶你到桌子的第二層。對於這一部分,我們將在所選指針和下一個指針之間進行二進制或內插搜索 - 即第二級中所有在前16位具有相同值的值。然而,當我們查看第二個表格時,我們已經知道該值的16位 - 因此,不是存儲該值的所有32位,我們只需要存儲該值的其他012位數據的其他012位存儲器位。
這意味着,而不是第二級佔用4兆字節,我們已經減少到2兆字節。除此之外,我們需要第一級表,但它只有65536x4 = 256K字節。
這幾乎肯定會提高整個數據集二進制搜索的速度。在最壞的情況下(使用二進制搜索第二級),我們可以進行多達17次比較(1 + log 65536)。但平均值會比這更好 - 因爲我們只有一百萬個項目,所以每個第二級「分區」中的平均值只能是1_000_000/65536 =〜15個項目,給出大約1 + log ( 16)= 5比較。在第二級使用內插搜索可能會進一步減少這一點,但是當您僅從5次比較開始時,就沒有太多餘地進行真正的重大改進。由於第二級平均只有15個項目,所以你使用的搜索類型不會有太大的變化 - 即使是線性搜索也會非常快。
當然,如果你想要更進一步,可以使用4級表(而不是整數中的每個字節)。然而,這是否會爲你節省更多的費用以避免麻煩,這是值得商榷的。至少從目前來看,我的猜測是你會做相當多的額外工作以節省很少的成本(只是存儲百萬個整數的最後一個字節顯然佔用1兆字節,並且三個級別的表導致了這一點佔用相當多的金額,所以你可以將數量增加一倍,以節省大約半個兆字節的數量。如果你處於一個稍微節省一點的情況下會產生巨大影響的情況,那就去做吧 - 但除此之外,我懷疑返回是否會證明額外投資。
可能是一個[布隆過濾器]的作業(http://en.wikipedia.org/wiki/Bloom_filter)? – 2012-03-17 21:28:50
你需要一個'insert'操作還是一次構建的字典,並且在查找過程中不再修改? – 2012-03-17 21:34:30
@Gareth Rees:你爲什麼不把它作爲答案發布,因此可以提高? – meriton 2012-03-17 21:47:36