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 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment