在Ruby的许多类实例中记忆数据的好方法是什么?

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

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 

HighOfNPeriods不同实例有不同的params和不同的@source_data

以下是指标的使用方法:

 class Strategy attr_accessor :indicators def initialize params ... end 

Strategy调用HighOfNPeriods.generate_data方法。 每个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. 从对象内部访问数据比从数据库中提取数据更快。

Ruby 1.9.3

创建一个类变量@@indicator_data ,它是一个哈希,以[@params,@source_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 

如果你不能在实例级别上记忆它,那么升级一级并使用类实例。

 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