cache_benchmark.rb

bahuvrihi (Simon Chiang), 03/19/2010 05:37 am

Download (1.8 kB)

 
1
require 'benchmark'
2

    
3
# A basic version of a dsl that registers key-value pairs onto a Class.  When
4
# looking up a key-value pair, Classes that use the dsl will check the
5
# registry of each ancestor in order, as if looking up a method.
6
#
7
# Call cache_ancestors! to cache the ancestry and speedup lookup.
8
module Dsl
9
  def self.extended(base)
10
    base.registry ||= {}
11
    base.cache = nil
12
  end
13
  
14
  def inherited(base)
15
    base.registry ||= {}
16
    base.cache = nil
17
  end
18
  
19
  attr_accessor :registry
20
  attr_accessor :cache
21
  
22
  def set(key, value)
23
    registry[key] = value
24
  end
25
  
26
  def value(key)
27
    each_ancestor do |ancestor|
28
      if ancestor.registry.has_key?(key)
29
        return ancestor.registry[key]
30
      end
31
    end
32
  end
33
  
34
  def cache_ancestors!
35
    @cache = ancestors
36
  end
37
  
38
  def each_ancestor
39
    (cache || ancestors).each {|ancestor| yield(ancestor)}
40
  end
41
end
42

    
43
# Now the benchmarks, first without caching (ie regenerate ancestors each
44
# time), then with caching to model performance with an each_ancestor method.
45
puts "Benchmark without cache"
46

    
47
class A
48
  extend Dsl
49
  set(:one, 1)
50
end
51

    
52
class B < A
53
  set(:two, 2)
54
end
55

    
56
class C < B
57
  set(:three, 3)
58
end
59

    
60
Benchmark.bm(20) do |x|
61
  n = 100000
62
  
63
  x.report "A.value(:one)" do
64
    n.times { A.value(:one) }
65
  end
66
  
67
  x.report "B.value(:two)" do
68
    n.times { B.value(:two) }
69
  end
70
  
71
  x.report "C.value(:three)" do
72
    n.times { C.value(:three) }
73
  end
74
end
75

    
76
puts
77
puts "Benchmark with cache"
78
A.cache_ancestors!
79
B.cache_ancestors!
80
C.cache_ancestors!
81

    
82
Benchmark.bm(20) do |x|
83
  n = 100000
84
  
85
  x.report "A.value(:one)" do
86
    n.times { A.value(:one) }
87
  end
88
  
89
  x.report "B.value(:two)" do
90
    n.times { B.value(:two) }
91
  end
92
  
93
  x.report "C.value(:three)" do
94
    n.times { C.value(:three) }
95
  end
96
  
97
  x.report "Array.new" do
98
    n.times { Array.new }
99
  end
100
end
101