Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
6
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

[Ruby]Hashのdefault_procで簡易キャッシュ

プログラム中で、ちょっとしたキャッシュを作りたい場合。もちろんメソッドを用意してもいいのですが、再利用性が低かったり、ちょっと大袈裟感があったりする場合も。

def foo
  %(a b c b a d).each do |id|
    puts sample_item(id)
  end
end
def sample_item id
  @sample_cache[id] ||= Sample.find(id)
end

そんな時には、Hashのdefault_procを使うと簡易的に代替できます。

def foo
  sample_cache = {}
  sample_cache.default_proc = proc do |hash, key|
    hash[key] = Sample.find(key)
  end
  %(a b c b a d).each do |id|
    puts sample_cache[id]
  end
end

コンストラクタにブロックを渡すのでもOK。

def foo
  sample_cache = Hash.new{|hash, key|
    hash[key] = Sample.find(key)
  }
  %(a b c b a d).each do |id|
    puts sample_cache[id]
  end
end

一応、レンスポンス的にもこちらの方が速い。

benchmark
require 'benchmark'

class TestClass
  def initialize keys, cycles
    @keys = keys
    @cycles = cycles
    @cache = {}
  end
  def get_data i
    @cache[i] ||= Time.now
  end
  def test1
    ret = {}
    (1..@keys).cycle(@cycles){|i| ret[i] = get_data(i)}
  end
  def test2
    ret = {}
    cache = Hash.new{|h,k| h[k]=Time.now}
    (1..@keys).cycle(@cycles){|i| ret[i] = cache[i]}
  end
end

t = TestClass.new(10000, 1000)
Benchmark.bm do |x|
  x.report { t.test1 }
  x.report { t.test2 }
  x.report { t.test2 }
  x.report { t.test1 }
end
result
       user     system      total        real
   2.860000   0.010000   2.870000 (  2.866910)
   2.150000   0.000000   2.150000 (  2.162081)
   2.180000   0.000000   2.180000 (  2.188632)
   2.980000   0.000000   2.980000 (  2.983547)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
6
Help us understand the problem. What are the problem?