2015-11-29 93 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"]}