LoginSignup
0
0

rubyで大量データをキャッシュした話

Posted at

はじめに

実装中、ループのたびに同じデータをデータベースから取得している処理がありました。このデータ取得の処理をキャッシュ化したかった。

クラス変数によるキャッシュ化

まず、クラス変数を使用してキャッシュを実装しました。クラス変数はクラスとそのサブクラスのすべてのインスタンス間で共有されるため、アプリケーション全体で一貫したデータを保持するのに適しています。
以下のような形

class DataCache
  @@cache = {}

  def self.store(key, value)
    @@cache[key] = value
  end

  def self.retrieve(key)
    @@cache[key]
  end
end

ただし、この実装ではサブクラスへの影響も考慮する必要があります。
DataCacheクラスのみで使用できるようにしたい。

クラスインスタンス変数によるキャッシュ化

次に、クラスインスタンス変数を使用したキャッシュ化を試みました。クラスインスタンス変数はクラス自体に固有で、クラスのすべてのインスタンスで共有されますが、サブクラスで共有されることはありません。

class DataCache
  @cache = {}

  def self.store(key, value)
    @cache[key] = value
  end

  def self.retrieve(key)
    @cache[key]
  end
end

この方法では、クラスインスタンス変数がクラスの各インスタンスで共有されないため、複数のインスタンスが作成されると再びデータベースからデータを取得することになります。

最終的な実装

最終的には、クラスインスタンス変数をクラスのシングルトンメソッド(クラスメソッド)としてアクセス可能にする方法を採用しました。これにより、クラスレベルでキャッシュが保持され、DataCacheクラスのすべてのインスタンスで共有されます。

class DataCache
  @cache = {}

  class << self
    attr_accessor :cache
  end

  def self.store(key, value)
    @cache[key] = value
  end

  def self.retrieve(key)
    @cache[key]
  end
end

まとめ

この実装により、DataCacheクラスのインスタンス間で共有されるキャッシュが作成され、パフォーマンスが大幅に向上しました。また、クラスインスタンス変数はサブクラスに影響を与えないため、DataCacheクラス限定での使用が可能です。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0