Skip to content

The wise choice for Ruby memoization

License

Notifications You must be signed in to change notification settings

Sorc96/memo_wise

This branch is 262 commits behind panorama-ed/memo_wise:main.

Folders and files

NameName
Last commit message
Last commit date
May 24, 2021
Jul 8, 2021
May 19, 2020
Jul 1, 2021
Nov 6, 2020
Jun 16, 2021
May 24, 2021
Feb 11, 2021
May 5, 2020
May 19, 2020
Feb 2, 2021
Oct 6, 2020
Jun 24, 2021
May 5, 2020
May 24, 2021
Jul 13, 2021
May 23, 2021
Jul 8, 2021
Feb 11, 2021
May 17, 2021

Repository files navigation

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

The same three methods are exposed for class methods as well:

class Example
  prepend MemoWise

  def self.class_slow_value(x)
    sleep x
    x
  end
  memo_wise self: :class_slow_value
end

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

Example.reset_memo_wise(:class_slow_value) # Resets all memoized results for class_slow_value

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

NOTE: 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.1, except as indicated below for specific gems. Benchmarks are run in GitHub Actions and updated in every PR that changes code.

Values >1.00x represent how much slower each gem’s memoized value retrieval is than the latest commit of memo_wise.

Method arguments memery (1.4.0) memoist* (0.16.2) memoized* (1.0.2) memoizer* (1.0.3) ddmemoize* (1.0.0)
() (none) 13.17x 2.64x 1.46x 3.10x 22.11x
(a) 9.76x 15.44x 11.98x 13.12x 17.83x
(a, b) 1.98x 2.25x 1.82x 1.98x 2.98x
(a:) 17.65x 23.64x 20.69x 21.61x 24.78x
(a:, b:) 4.16x 3.94x 3.53x 3.67x 4.74x
(a, b:) 3.96x 3.72x 3.27x 3.42x 4.47x
(a, *args) 1.93x 2.25x 1.93x 1.95x 2.94x
(a:, **kwargs) 3.06x 2.38x 2.10x 2.20x 2.47x
(a, *args, b:, **kwargs) 1.52x 1.79x 1.65x 1.65x 1.95x

*Indicates a benchmark run on Ruby 2.7.3 because the gem raises errors in Ruby 3.0.1 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!

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

We use dokaz to test all code examples in this README.md file, and all other non-code documentation. To run dokaz locally:

bundle exec dokaz

A Note on Testing

When testing memoized module methods, note that some testing setups will reuse the same instance (which includes/extends/prepends the module) across tests, which can result in confusing test failures when this differs from how you use the code in production.

For example, Rails view helpers are modules that are commonly tested with a shared view instance. Rails initializes a new view instance for each web request so any view helper methods would only be memoized for the duration of that web request, but in tests (such as when using rspec-rails's helper), the memoization may persist across tests. In this case, simply reset the memoization between your tests with something like:

after(:each) { helper.reset_memo_wise }

Logo

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 --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.

About

The wise choice for Ruby memoization

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 99.9%
  • Shell 0.1%