2015-11-29 108 views
0

我1000萬散列大小的工作...紅寶石。慢哈希值查找與大的哈希的

hash={'Aatater'=>2, 'Bbabber'=>3, 'Xaazerx'=>2, 'Caackersc'=>1} 

尋找一個重點是赫然快。即使在關鍵的哈希年底存在...

hash['Caackersc']=>1 

但如果搜索中存在的哈希這將是痛苦而緩慢深的值。

hash.key(1)=>"Caackersc" 

所以,我第一次嘗試在搜索一個值時獲得很高的速度。我以爲我會顛倒散列。但是這會導致重複值被刪除。

hash.invert{ 2=>'Xaazerx', 3=>'Bbabber', 1=>'Caackersc'} 

於是,我又試圖...反轉散列自己用了丟失數據通過發佈指數befor每一個新的關鍵。

I_hash=Hash.new 

hash.to_a.each_with_index{|h,i| i_hash[[i.to_s,h[1].to_s]]=h[0]} 

{["0","2"]=>'Aatater', ["1","3"]=>'Bbabber', ["2","2"]=>' Xaazerx', ["3","1"]=>'Caackersc'} 

所以,此時我可以用相同的惡意快速搜索新密鑰。

i_hash[["1","3"]] => "Bbabber" 

但現在...我希望鍵的索引部分可以用正則表達式找到嗎?

I_hash[/\d/,"3"]=>fail, nil 

所以......這是爲了加快值搜索我的最好的嘗試,但它只會在我的情況下工作,如果我可以的正則表達式關鍵的第一陣列。

+3

爲什麼你要處理十十萬人所有的哈希?你爲什麼不使用數據庫? –

+0

如果OP不需要長期持久性,並且它滿足他們的性能需求,我認爲使用散列並不瘋狂。 –

+0

我試過dbm。我相信尋找鍵對於這個應用來說有點慢......我可能需要重新測試,雖然......我沒有超過內存,所以它沒有必要 –

回答

4

你有正確的想法。對於你的倒排散列,你希望每個值都是原始散列中相應鍵的數組。類似這樣的:

hash = { 'Aatater' => 2, 'Bbabber' => 3, 'Xaazerx' => 2, 'Caackersc' => 1 } 

inv_hash = hash.keys.group_by {|k| hash[k] } 

p inv_hash 
# => { 2 => [ "Aatater", "Xaazerx" ], 
#  3 => [ "Bbabber" ], 
#  1 => [ "Caackersc" ] } 

p inv_hash[2] 
# => [ "Aatater", "Xaazerx" ] 
+1

'inv_hash = hash.keys.group_by {| k |哈希[k]}' – steenslag

+0

很棒,@steenslag。我已經更新了我的答案。 –

-1

如果您遇到性能問題,可以考慮使用redis

+0

redis是我關注的一個建議,我安裝了一個服務器集羣,並在網上找到一個示例教程...但是我沒有看到在數據庫中搜索一個值。 redis只支持關鍵字搜索? –

+0

從鍵盤訪問數據的速度要快得多,這是肯定的。你可以有兩個數據庫,一個用於正常散列,一個用於倒置散列。否則,一個SQL數據庫應該完成這項工作 –

1

你也可以計算這樣的逆:

hash.each_with_object({}) { |(k,v),h| (h[v] ||= []) << k } 
    #=> {2=>["Aatater", "Xaazerx"], 3=>["Bbabber"], 1=>["Caackersc"]}