MemoWise

Tests Code Coverage Yard Docs Inline docs Gem Version Gem Downloads

Why MemoWise?

MemoWise is the wise choice for Ruby memoization, featuring:

Installation

Add this line to your application's Gemfile:

gem 'memo_wise'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install memo_wise

Usage

When you prepend MemoWise within a class or module, MemoWise exposes three methods:

class Example
  prepend MemoWise
  def slow_value(x)
    sleep x
    x
  end
  memo_wise :slow_value
end

ex = Example.new
ex.slow_value(2) # => 2 # Sleeps for 2 seconds before returning
ex.slow_value(2) # => 2 # Returns immediately because the result is memoized

ex.reset_memo_wise(:slow_value) # Resets all memoized results for slow_value
ex.slow_value(2) # => 2 # Sleeps for 2 seconds before returning
ex.slow_value(2) # => 2 # Returns immediately because the result is memoized
# NOTE: Memoization can also be reset for all methods, or for just one argument.

ex.preset_memo_wise(:slow_value, 3) { 4 } # Store 4 as the result for slow_value(3)
ex.slow_value(3) # => 4 # Returns immediately because the result is memoized
ex.reset_memo_wise # Resets all memoized results for all methods on ex

Methods which take implicit or explicit block arguments cannot be memoized.

For more usage details, see our detailed documentation.

Benchmarks

Benchmarks measure memoized value retrieval time using benchmark-ips. All benchmarks are run on Ruby 3.0.0, except as indicated below for specific gems. Benchmarks are run in GitHub Actions and updated in every PR that changes code.

Method arguments memo_wise (0.1.0) memery (1.3.0) memoist* (0.16.2) memoized* (1.0.2) memoizer* (1.0.3)
() (none) baseline 14.69x slower 2.59x slower 1.15x slower 2.91x slower
(a, b) baseline 1.93x slower 2.20x slower 1.79x slower 1.96x slower
(a:, b:) baseline 3.01x slower 2.41x slower 2.18x slower 2.28x slower
(a, b:) baseline 1.49x slower 1.75x slower 1.51x slower 1.60x slower
(a, *args) baseline 1.92x slower 2.23x slower 1.94x slower 1.98x slower
(a:, **kwargs) baseline 3.08x slower 2.48x slower 2.17x slower 2.28x slower
(a, *args, b:, **kwargs) baseline 1.55x slower 1.73x slower 1.65x slower 1.67x slower

*Indicates a benchmark run on Ruby 2.7.2 because the gem raises errors in Ruby 3.0.0 due to its incorrect handling of keyword arguments.

You can run benchmarks yourself with:

$ cd benchmarks
$ bundle install
$ bundle exec ruby benchmarks.rb

If your results differ from what's posted here, let us know!

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.

Documentation

Documentation is Automatically Generated

We maintain API documentation using YARD, which is published automatically at RubyDoc.info. To edit documentation locally and see it rendered in your browser, run:

bundle exec yard server

Documentation Examples are Automatically Tested

We use yard-doctest to test all code examples in our YARD documentation. To run doctest locally:

bundle exec yard doctest

MemoWise's logo was created by Luci Cooke. The logo is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/panorama-ed/memo_wise. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

Releasing

To make a new release of MemoWise to RubyGems, first install the release dependencies (e.g. rake) as follows:

bundle config set --local with 'release'
bundle install

Then carry out these steps:

  1. Update CHANGELOG.md:

    • Add an entry for the upcoming version x.y.z
    • Move content from Unreleased to the upcoming version x.y.z
    • Commit with title Update CHANGELOG.md for x.y.z
  2. Update lib/memo_wise/version.rb

    • Replace with upcoming version x.y.z
    • Commit with title Bump version to x.y.z
  3. bundle exec rake release

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the MemoWise project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.