RubyMemoized
RubyMemoized makes it easy to memoize methods, even if they have arguments or blocks,
by making memoization as easy as declaring a method private.
To experiment with that code, run bin/console
for an interactive prompt.
For more information about the motivation behind the gem, please see this blog post.
Installation
Add this line to your application's Gemfile:
gem 'ruby_memoized'
And then execute:
$ bundle
Or install it yourself as:
$ gem install ruby_memoized
Usage
Suppose we have the following class:
class FibonacciCalculator
def calculate(n)
return n if (0..1).include?(n)
calculate(n - 1) + calculate(n - 2)
end
end
Right now, when we try to use this FibonacciCalculator
for any larger number, it takes quite a while to compute since
it has to perform the method calls in line 34.
One of the ways we can make this computation much faster is to save (memoize) the pieces so they return immediately. Let's do that in a separate method:
class FibonacciCalculator
def calculate(n)
return n if (0..1).include?(n)
calculate(n - 1) + calculate(n - 2)
end
memoized
def memoized_calculate(n)
return n if (0..1).include?(n)
memoized_calculate(n - 1) + memoized_calculate(n - 2)
end
end
Here, we put a call to the memoized
class method. This class method will allow us to make sure that the outputs of
any method calls below it will be saved (memoized).
Let's see the how the performance of one stacks up against the other for an n
of 35.
user system total real
with memoization 0.000000 0.000000 0.000000 ( 0.000469)
without memoization 46.010000 0.160000 46.170000 (46.597599)
Cool, but now suppose we wrote another method that we didn't want memoized after memoized_calculate
.
We could unmemoize it by doing the following:
class FibonacciCalculator
include RubyMemoized
memoized
def memoized_calculate(n)
return n if (0..1).include?(n)
memoized_calculate(n - 1) + memoized_calculate(n - 2)
end
unmemoized
def calculate(n)
return n if (0..1).include?(n)
calculate(n - 1) + calculate(n - 2)
end
end
Alright, that sounds all well and good. But what if we really didn't wanna call include RubyMemoized
everywhere but
still wanted to use memoization?
We could just add it to Object
!
class Object
include RubyMemoized
end
Now we make objects that use memoized
/unmemoized
willy-nilly.
class RandomThing
memoize
def hardcore_calculation
# TODO: Write really hardcore calculation.
end
end
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/kklimuk/memoized. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.