Last active
August 29, 2015 14:05
-
-
Save printercu/622037a07431e5c45d53 to your computer and use it in GitHub Desktop.
Benchmarking thread-safe class_attribute
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark' | |
require 'active_support/all' | |
class Class | |
def class_attribute2(*attrs) | |
options = attrs.extract_options! | |
instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true) | |
instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true) | |
instance_predicate = options.fetch(:instance_predicate, true) | |
attrs.each do |name| | |
define_singleton_method(name) { nil } | |
define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate | |
ivar = "@#{name}" | |
define_singleton_method name do | |
if instance_variable_defined?(ivar) | |
instance_variable_get(ivar) | |
else | |
superclass.send(name) rescue nil | |
end | |
end | |
define_singleton_method "#{name}=" do |val| | |
instance_variable_set(ivar, val) | |
if singleton_class? | |
class_eval do | |
define_method name do | |
if instance_variable_defined?(ivar) | |
instance_variable_get ivar | |
else | |
singleton_class.public_send name | |
end | |
end | |
end | |
end | |
val | |
end | |
if instance_reader | |
define_method(name) do | |
if instance_variable_defined?(ivar) | |
instance_variable_get ivar | |
else | |
self.class.public_send name | |
end | |
end | |
define_method("#{name}?") { !!public_send(name) } if instance_predicate | |
end | |
attr_writer name if instance_writer | |
end | |
end | |
end | |
class Grand | |
class_attribute :value | |
class_attribute2 :value2 | |
end | |
class Parent < Grand | |
end | |
class Child < Parent | |
end | |
n = 1_000_000 | |
singleton = Grand.new.singleton_class | |
Benchmark.bmbm do |b| | |
b.report(:setter_orig) { n.times { |i| Grand.value = 1 } } | |
b.report(:setter_patch) { n.times { |i| Grand.value2 = 1 } } | |
b.report(:singleton_setter_orig) { n.times { |i| Grand.value = 1 } } | |
b.report(:singleton_setter_patch) { n.times { |i| Grand.value2 = 1 } } | |
b.report(:getter_direct_orig) { n.times { |i| Grand.value } } | |
b.report(:getter_direct_patch) { n.times { |i| Grand.value2 } } | |
b.report(:getter_child_orig) { n.times { |i| Parent.value } } | |
b.report(:getter_child_patch) { n.times { |i| Parent.value2 } } | |
b.report(:getter_grand_child_orig) { n.times { |i| Child.value } } | |
b.report(:getter_grand_child_patch) { n.times { |i| Child.value2 } } | |
end |
Author
printercu
commented
Aug 24, 2014
Benchmark.ips do |b|
b.report('set_orig') { Grand.value = 1 }
b.report('set_patch') { Grand.value2 = 1 }
b.compare!
end
Benchmark.ips do |b|
b.report('singleton_set_orig') { Grand.value = 1 }
b.report('singleton_set_patch') { Grand.value2 = 1 }
b.compare!
end
Benchmark.ips do |b|
b.report('get_direct_orig') { Grand.value }
b.report('get_direct_patch') { Grand.value2 }
b.report('get_child_orig') { Parent.value }
b.report('get_child_patch') { Parent.value2 }
b.report('get_gr_child_orig') { Child.value }
b.report('get_gr_child_patch') { Child.value2 }
b.compare!
end
Calculating -------------------------------------
set_orig 11457 i/100ms
set_patch 21204 i/100ms
-------------------------------------------------
set_orig 231021.6 (±21.0%) i/s - 1111329 in 5.040793s
set_patch 1805810.9 (±13.3%) i/s - 8820864 in 4.999600s
Comparison:
set_patch: 1805810.9 i/s
set_orig: 231021.6 i/s - 7.82x slower
Calculating -------------------------------------
singleton_set_orig 11859 i/100ms
singleton_set_patch 22527 i/100ms
-------------------------------------------------
singleton_set_orig 234758.3 (±19.7%) i/s - 1138464 in 5.047345s
singleton_set_patch 1838948.8 (±12.2%) i/s - 9010800 in 4.998438s
Comparison:
singleton_set_patch: 1838948.8 i/s
singleton_set_orig: 234758.3 i/s - 7.83x slower
Calculating -------------------------------------
get_direct_orig 28707 i/100ms
get_direct_patch 23137 i/100ms
get_child_orig 27768 i/100ms
get_child_patch 21162 i/100ms
get_gr_child_orig 28401 i/100ms
get_gr_child_patch 18447 i/100ms
-------------------------------------------------
get_direct_orig 4496212.6 (±11.5%) i/s - 22018269 in 4.994925s
get_direct_patch 1818551.3 (±12.2%) i/s - 8907745 in 4.999383s
get_child_orig 4507921.5 (±11.7%) i/s - 21992256 in 4.996994s
get_child_patch 1020330.4 (±11.9%) i/s - 5015394 in 5.004444s
get_gr_child_orig 4427673.4 (±13.3%) i/s - 21499557 in 4.994001s
get_gr_child_patch 718534.3 (±10.5%) i/s - 3541824 in 4.998001s
Comparison:
get_child_orig: 4507921.5 i/s
get_direct_orig: 4496212.6 i/s - 1.00x slower
get_gr_child_orig: 4427673.4 i/s - 1.02x slower
get_direct_patch: 1818551.3 i/s - 2.48x slower
get_child_patch: 1020330.4 i/s - 4.42x slower
get_gr_child_patch: 718534.3 i/s - 6.27x slower
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment