Skip to content

Instantly share code, notes, and snippets.

@dekellum
Last active June 23, 2016 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dekellum/e6aff483c8d6b208f281bf5d92c113e6 to your computer and use it in GitHub Desktop.
Save dekellum/e6aff483c8d6b208f281bf5d92c113e6 to your computer and use it in GitHub Desktop.
Benchmark constant access vs two ways to support overrides in derived class
#!/usr/bin/ruby
# Adapted from https://github.com/bbatsov/ruby-style-guide/issues/328#issuecomment-227967489
require 'benchmark'
n = 5000000
$priv_const = ( ARGV[0] == 'priv_const' )
class C1
# == Constants ==
BLACK = 0
RED = 1
GREEN = 2
BLUE = 3
YELLOW = 4
VIOLET = 5
PURPLE = 6
BROWN = 7
PINK = 8
WHITE = 9
# Note: This won't work with use_via_self
if $priv_const
private_constant :BLACK, :RED, :GREEN, :BLUE, :YELLOW,
:VIOLET,:PURPLE, :BROWN, :PINK, :WHITE
end
# == Wrapper methods (which could be overridden) ==
def self.black
BLACK
end
def self.red
RED
end
def self.green
GREEN
end
def self.blue
BLUE
end
def self.yellow
YELLOW
end
def self.violet
VIOLET
end
def self.purple
PURPLE
end
def self.brown
BROWN
end
def self.pink
PINK
end
def self.white
WHITE
end
# Use defined constants directly
def self.use_direct( i )
case i
when BLACK
0
when RED
1
when GREEN
2
when BLUE
3
when YELLOW
4
when VIOLET
5
when PURPLE
6
when BROWN
7
when PINK
8
when WHITE
9
end
end
# Use `self::` for contant lookup, so that these constants may be
# effectively "overridden" in a derived class.
def self.use_via_self( i )
case i
when self::BLACK
0
when self::RED
1
when self::GREEN
2
when self::BLUE
3
when self::YELLOW
4
when self::VIOLET
5
when self::PURPLE
6
when self::BROWN
7
when self::PINK
8
when self::WHITE
9
end
end
# Use the wrapper methods for access to the underlying (potentially
# private) constants.
def self.use_wrappers( i )
case i
when black
0
when red
1
when green
2
when blue
3
when yellow
4
when violet
5
when purple
6
when brown
7
when pink
8
when white
9
end
end
end
# Derived class using constant "override" for C2.use_via_self
class C2 < C1
BLACK = 0
RED = 1
GREEN = 2
BLUE = 3
YELLOW = 4
VIOLET = 5
PURPLE = 6
BROWN = 7
PINK = 8
WHITE = 9
end
# Derived class using wrapper override for C3.use_wrappers
class C3 < C1
BLACK = 0
RED = 1
GREEN = 2
BLUE = 3
YELLOW = 4
VIOLET = 5
PURPLE = 6
BROWN = 7
PINK = 8
WHITE = 9
if $priv_const
private_constant :BLACK, :RED, :GREEN, :BLUE, :YELLOW,
:VIOLET,:PURPLE, :BROWN, :PINK, :WHITE
end
def self.black
BLACK
end
def self.red
RED
end
def self.green
GREEN
end
def self.blue
BLUE
end
def self.yellow
YELLOW
end
def self.violet
VIOLET
end
def self.purple
PURPLE
end
def self.brown
BROWN
end
def self.pink
PINK
end
def self.white
WHITE
end
end
Benchmark.bm(26) do |x|
x.report('C1.use_direct:') { 1.upto(n) { |i| C1.use_direct(i%10); } }
unless $priv_const
x.report('C1.use_via_self:') { 1.upto(n) { |i| C1.use_via_self(i%10); } }
end
x.report('C1.use_wrappers:') { 1.upto(n) { |i| C1.use_wrappers(i%10); } }
unless $priv_const
x.report('C2.use_via_self:') { 1.upto(n) { |i| C2.use_via_self(i%10); } }
end
x.report('C3.use_wrappers:') { 1.upto(n) { |i| C3.use_wrappers(i%10); } }
end
ruby -v ./const-benchmark.rb
ruby 2.2.5p319 (2016-04-26 revision 54774) [x86_64-linux]
user system total real
C1.use_direct: 1.110000 0.000000 1.110000 ( 1.107700)
C1.use_via_self: 1.630000 0.000000 1.630000 ( 1.631611)
C1.use_wrappers: 1.690000 0.000000 1.690000 ( 1.694374)
C2.use_via_self: 1.580000 0.000000 1.580000 ( 1.581633)
C3.use_wrappers: 1.640000 0.000000 1.640000 ( 1.640261)
ruby -v ./const-benchmark.rb priv_const
ruby 2.2.5p319 (2016-04-26 revision 54774) [x86_64-linux]
user system total real
C1.use_direct: 1.100000 0.000000 1.100000 ( 1.093155)
C1.use_wrappers: 1.590000 0.000000 1.590000 ( 1.598704)
C3.use_wrappers: 1.610000 0.000000 1.610000 ( 1.601593)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment