Stop using method missing for singleton delegation.

This saved about 46 array allocations per request on an extremely simple
application.  The delegation happened in the notification subsystem
which is a hotspot, so this should result in even more savings with
larger apps.

Squashed commit of the following:

commit 41eef0d1479526f7de25fd4391d98e61c126d9f5
Author: Aaron Patterson <aaron.patterson@gmail.com>
Date:   Wed Nov 6 16:32:31 2013 -0800

    speed up notifications

commit 586b4a18656f66fb2c518fb8e8fee66a016e8ae6
Author: Aaron Patterson <aaron.patterson@gmail.com>
Date:   Wed Nov 6 16:31:05 2013 -0800

    speed up runtime registry methods

commit b67d074cb4314df9a88438f785868cef77e583d7
Author: Aaron Patterson <aaron.patterson@gmail.com>
Date:   Wed Nov 6 16:28:12 2013 -0800

    change method name and make it public
This commit is contained in:
Aaron Patterson 2013-11-06 16:32:47 -08:00
parent 4d15661d6c
commit 5584ddc43d
5 changed files with 15 additions and 9 deletions

View File

@ -13,5 +13,10 @@ module ActiveRecord
extend ActiveSupport::PerThreadRegistry
attr_accessor :connection_handler, :sql_runtime, :connection_id
[:connection_handler, :sql_runtime, :connection_id].each do |val|
class_eval %{ def self.#{val}; instance.#{val}; end }, __FILE__, __LINE__
class_eval %{ def self.#{val}=(x); instance.#{val}=x; end }, __FILE__, __LINE__
end
end
end

View File

@ -23,6 +23,9 @@ module ActiveSupport
def set_cache_for(local_cache_key, value)
@registry[local_cache_key] = value
end
def self.set_cache_for(l, v); instance.set_cache_for l, v; end
def self.cache_for(l); instance.cache_for l; end
end
# Simple memory backed cache. This cache is not thread safe and is intended only

View File

@ -178,7 +178,7 @@ module ActiveSupport
end
def instrumenter
InstrumentationRegistry.instrumenter_for(notifier)
InstrumentationRegistry.instance.instrumenter_for(notifier)
end
end

View File

@ -32,21 +32,19 @@ module ActiveSupport
#
# If the class has an initializer, it must accept no arguments.
module PerThreadRegistry
def instance
Thread.current[name] ||= new
end
protected
def method_missing(name, *args, &block) # :nodoc:
# Caches the method definition as a singleton method of the receiver.
define_singleton_method(name) do |*a, &b|
per_thread_registry_instance.public_send(name, *a, &b)
instance.public_send(name, *a, &b)
end
send(name, *args, &block)
end
private
def per_thread_registry_instance
Thread.current[name] ||= new
end
end
end

View File

@ -94,7 +94,7 @@ module ActiveSupport
private
def event_stack
SubscriberQueueRegistry.get_queue(@queue_key)
SubscriberQueueRegistry.instance.get_queue(@queue_key)
end
end