在Rails中实现大型2D查找表的最佳方法

时间:2015-08-16 20:24:08

标签: ruby-on-rails ruby lookup-tables

我正在开发一个Rails应用程序,我的一个动作比较了两个相同类型的对象并返回0到1之间的十进制值。大约有800个对象需要进行比较,因此大约有800 * 800可以返回的可能的十进制值。每个动作调用都需要大约300个左右的比较,这些比较是通过API进行的。

由于需要多少API调用,我决定最好的方法是创建一个查找表,其中包含本地存储的所有800 * 800 API比较值,以避免不得不依赖于已调用的API限制和每次通话的显着开销。

基本上我已经确定查找表最适合这个任务(虽然我也对这方面的建议持开放态度。)

我的问题是:在轨道中使用~800“行”和~800“列”实现二维查找表的最佳方法是什么?例如,如果我想比较对象754和348,最好是为行和列创建模型并访问小数比较,如:

object1.754.object2.348 # => 0.8738

或者我应该将所有值存储在CSV或类似的东西中?如果这是更好的方法,我该如何设置呢?我对铁轨世界比较陌生,所以如果一个明显的答案悬在我面前,我会道歉!

请记住,这种方法的重点是避免API调用的开销,从而避免最终用户的大量等待时间,因此我正在寻找最有效的方法来完成此任务!

2 个答案:

答案 0 :(得分:1)

我会考虑散列哈希值,因此您可以使用以下方法检索值:

my_hash[754][348]
=> 0.8738

如果您可能尚未加载特定组合的值,那么您需要小心使用:

my_hash[754].try(:[],348)

加载哈希值时可能会有一些细微之处,这有利于使用hashie gem。

https://rubygems.org/gems/hashie/versions/3.4.2

如果您想要保留这些值,那么可以使用serialize将其写入数据库,如果您愿意,也可以扩展该方法以提供值的到期日期。

答案 1 :(得分:0)

我在比较大量电子书的内容时遇到了类似的问题,我将所有已经比较的结果存储在我与Marshal序列化的矩阵中,查找键是文件路径的MD5值的二维数组。 在这里,我添加了为此任务创建的Matric类。

require 'digest/md5' 

class Matrix
  attr_accessor :path, :store

  def initialize path
    @path = path
    @store = File.open(@path,'rb') { |f| Marshal.load(f.read) } rescue Hash.new(nil)
  end

  def save
    File.open(@path,'wb') { |f| f.write(Marshal.dump(@store)) }
    self
  end

  def add file1, file2, value
    @store[[Digest::MD5.hexdigest(file1), Digest::MD5.hexdigest(file2)]] = value
  end

  def has? file1, file2
    !@store[[Digest::MD5.hexdigest(file1), Digest::MD5.hexdigest(file2)]].nil?
  end

  def value file1, file2
    @store[[Digest::MD5.hexdigest(file1), Digest::MD5.hexdigest(file2)]]
  end

  def each &blk
    @store.each &blk
  end

end