Permalink
Browse files

Some performance tweaks to ActiveSupport::Memoizable

Signed-off-by: Joshua Peek <josh@joshpeek.com>
  • Loading branch information...
1 parent 001c8be commit 911c2c381347ffb04615896ee6afe45277eeb103 @tarmo tarmo committed with josh Jul 15, 2008
Showing with 8 additions and 2 deletions.
  1. +4 −2 activesupport/lib/active_support/memoizable.rb
  2. +4 −0 activesupport/test/memoizable_test.rb
@@ -7,10 +7,12 @@ def self.included(base) #:nodoc:
module ClassMethods
def memoize(symbol)
original_method = "_unmemoized_#{symbol}"
+ raise "Already memoized #{symbol}" if instance_methods.map(&:to_s).include?(original_method)
+
alias_method original_method, symbol
class_eval <<-EOS, __FILE__, __LINE__
def #{symbol}
- if instance_variable_defined?(:@#{symbol})
+ if defined? @#{symbol}
@#{symbol}
else
@#{symbol} = #{original_method}
@@ -22,7 +24,7 @@ def #{symbol}
def freeze
methods.each do |method|
- if m = method.to_s.match(/^_unmemoized_(.*)/)
+ if m = method.to_s.match(/\A_unmemoized_(.*)/)
@wuputah
wuputah Jul 15, 2008

If the goal is performance, you could eliminate the Regexp all together:

if method.to_s[0, 12] == '_unmemoized_'
@ send(method[12, m.length]).freeze@
end

It’d make a much bigger difference then changing ^ to \A.

@wuputah
wuputah Jul 15, 2008

Err, m.length should have been method.length.

send(m[1]).freeze
end
end
@@ -41,5 +41,9 @@ def test_memoization_frozen_with_nil_value
person.freeze
assert_equal nil, person.age
end
+
+ def test_double_memoization
+ assert_raise(RuntimeError) { Person.memoize :name }
+ end
end
end

1 comment on commit 911c2c3

@josh
Member
josh commented on 911c2c3 Jul 15, 2008

Whip that up and pull request me

Please sign in to comment.