5

考虑:生成数据的对象的许多实例。每次运行只生成一次该数据会很棒。

class HighOfNPeriods < Indicator
  def generate_data
    @indicator_data = DataStream.new
    (0..@source_data.data.count - 1).each do |i|
      if i < @params[:n_days]
      ...
      @indicator_data.add one_data
    end
  end

HighOfNPeriodswith differentparams和 different有不同的实例@source_data

以下是指标的使用方法:

class Strategy
  attr_accessor :indicators

  def initialize params
    ...
  end

该方法HighOfNPeriods.generate_data是从内部调用的Strategy。每个Strategy都有一个 的新实例HighOfNPeriods,因此不可能将其作为某种全局值提取出来。除此之外,它不应该是全球性的。

unless @indicator_data不会工作,因为数据需要在多个HighOfNPeriods.

所以,问题是:

What is a good way to memoize the instance variable `indicator_data` 
or the object `HighOfNPeriods` when there are many different instances, 
some of which have different data?

一种解决方案是使用 ActiveRecord 存储数据,但这并不是我现在真正想要的方式,因为:

  1. 并不是所有生成的数据都可以提前生成,因为params的排列太多了。查看之前是否已生成,然后根据需要生成(并保存)会更有意义。
  2. 生成数据不需要很长时间。它可能会生成一次并每次运行使用数百次。
  3. 从对象内部访问数据比从数据库中提取数据要快。

红宝石 1.9.3

4

2 回答 2

4

如果您无法在实例级别上记住它,请上一层并使用类实例。

class Foo
  # I used *args here for simplicity of the example code.
  def generate_data *args
    if res = self.class.cache[args]
      puts "Data in cache for #{args.inspect} is #{res}"
      return res
    end

    puts "calculating..."
    p1, p2 = args
    res = p1 * 10 + p2
    self.class.cache[args] = res
    res
  end

  def self.cache
    @cache ||= {}
    @cache
  end
end


puts Foo.new.generate_data 1, 2 
puts Foo.new.generate_data 3, 4
puts Foo.new.generate_data 1, 2
# >> calculating...
# >> 12
# >> calculating...
# >> 34
# >> Data in cache for [1, 2] is 12
# >> 12
于 2012-11-25T15:59:06.620 回答
1

创建一个类变量@@indicator_data,它是一个散列,[@params,@source_data]作为键和@indicator_data作为值。然后,在创建时,对@@indicator_data[[@params,@source_data]].

class HighOfNPeriods < Indicator
  @@indicator_data = {}
  def generate_data
    @indicator_data = @@indicator_data[[@params, @source_data]] ||= DataStream.new
    ...
  end
end
于 2012-11-25T15:57:02.823 回答