【问题标题】:Ruby. Slow hash value look up with large hash's红宝石。使用大散列查找慢散列值
【发布时间】:2015-11-30 14:45:10
【问题描述】:

我正在使用 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'}

然后我尝试在不丢失数据的情况下自己反转哈希...通过在每个新键之前发出索引号。

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

所以...这是我加快值搜索速度的最佳尝试,但只有当我可以正则表达式键的第一个数组时,它才会在我的情况下起作用。

【问题讨论】:

  • 你为什么要处理一千万大小的哈希?你为什么不使用数据库?
  • 如果 OP 不需要长期持久化,并且满足他们的性能需求,我不认为使用哈希是疯狂的。
  • 我试过dbm。我相信搜索密钥对于这个应用程序来说有点慢......我可能需要重新测试......我没有超过 ram 所以它没有必要

标签: ruby


【解决方案1】:

你的想法是对的。对于您的反向哈希,您希望每个值都是原始哈希中相应键的数组。像这样的:

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" ]

【讨论】:

  • inv_hash = hash.keys.group_by{|k| hash[k] }
【解决方案2】:

你也可以像这样计算逆:

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

【讨论】:

    【解决方案3】:

    如果遇到性能问题,可以考虑使用redis。

    【讨论】:

    • redis 是我遵循的建议,我安装了一个服务器集群,并在网上找到了一个示例教程......但无论如何我都看不到在数据库中搜索值。 redis 只支持key search?
    • 从键访问数据要快一个数量级,这是肯定的。您可以有两个数据库,一个用于普通哈希,一个用于反向哈希。否则一个 SQL 数据库应该完成这项工作
    猜你喜欢
    • 1970-01-01
    • 2010-12-18
    • 2010-12-23
    • 2019-11-03
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多