Skip to content

Commit

Permalink
Merge pull request #297 from panorama-ed/ruby-3.2.0
Browse files Browse the repository at this point in the history
Update benchmark gems and test on Ruby 3.2
  • Loading branch information
JacobEvelyn authored Feb 13, 2023
2 parents a0e6a99 + d621540 commit f66db59
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 63 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
matrix:
# Due to https://github.com/actions/runner/issues/849, we have to use
# quotes for '3.0' -- without quotes, CI sees '3' and runs the latest.
ruby: [2.4, 2.5, 2.6, 2.7, '3.0', 3.1, jruby, truffleruby-head]
ruby: [2.4, 2.5, 2.6, 2.7, '3.0', 3.1, 3.2, jruby, truffleruby-head]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand All @@ -24,7 +24,7 @@ jobs:
- name: Set bundler environment variables
run: |
echo "BUNDLE_WITHOUT=checks:docs" >> $GITHUB_ENV
if: matrix.ruby != 3.1
if: matrix.ruby != 3.2

# Use 'bundler-cache: true' instead of actions/cache as advised:
# * https://github.com/actions/cache/blob/main/examples.md#ruby---bundler
Expand All @@ -40,18 +40,18 @@ jobs:
files: ./coverage/coverage.xml
fail_ci_if_error: true # optional (default = false)
verbose: true # optional (default = false)
if: matrix.ruby == 3.1
if: matrix.ruby == 3.2

- run: bundle exec rubocop
if: matrix.ruby == 3.1
if: matrix.ruby == 3.2

- run: |
bundle exec yard doctest
bundle exec dokaz
if: matrix.ruby == 3.1
if: matrix.ruby == 3.2
- name: Run benchmarks on Ruby 2.7 or 3.1
- name: Run benchmarks on Ruby 2.7 or 3.2
run: |
BUNDLE_GEMFILE=benchmarks/Gemfile bundle install --jobs 4 --retry 3
BUNDLE_GEMFILE=benchmarks/Gemfile bundle exec ruby benchmarks/benchmarks.rb
if: matrix.ruby == '2.7' || matrix.ruby == '3.1'
if: matrix.ruby == '2.7' || matrix.ruby == '3.2'
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.2
3.2.1
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ _No breaking changes!_

**Project enhancements:**

- Updated benchmark results in `README.md` to Ruby 3.1.2 and 2.7.6
- Updated benchmark results in `README.md` to Ruby 3.2.1 and 2.7.7
- Updated `Dry::Core` gem version to 1.0.0 in benchmarks
- Updated `Memery` gem version to 1.4.1 in benchmarks
- Updated `Memoized` gem version to 1.1.1 in benchmarks
- Reorganized `CHANGELOG.md` for improved clarity and completeness
[[#282](https://github.com/panorama-ed/memo_wise/pull/282)]
Expand Down
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ end

# Excluded from CI except on latest MRI Ruby, to reduce compatibility burden
group :docs do
gem "dokaz"
gem "redcarpet", "~> 3.5"
gem "dokaz", "~> 0.0.5"
gem "redcarpet", "~> 3.6"
gem "yard", "~> 0.9"
gem "yard-doctest", "~> 0.1"
end
Expand Down
34 changes: 18 additions & 16 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,24 @@ GEM
concurrent-ruby (1.1.9)
diff-lcs (1.5.0)
docile (1.4.0)
dokaz (0.0.4)
dokaz (0.0.5)
ansi
rouge
rouge (~> 4)
slop (~> 3)
i18n (1.10.0)
concurrent-ruby (~> 1.0)
json (2.6.3)
minitest (5.15.0)
parallel (1.21.0)
parser (3.1.1.0)
parallel (1.22.1)
parser (3.2.0.0)
ast (~> 2.4.1)
rack (3.0.0)
rainbow (3.1.1)
rake (13.0.6)
redcarpet (3.5.1)
regexp_parser (2.2.1)
redcarpet (3.6.0)
regexp_parser (2.6.1)
rexml (3.2.5)
rouge (3.28.0)
rouge (4.1.0)
rspec (3.11.0)
rspec-core (~> 3.11.0)
rspec-expectations (~> 3.11.0)
Expand All @@ -60,16 +61,17 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0)
rspec-support (3.11.0)
rubocop (1.25.1)
rubocop (1.43.0)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.1.0.0)
parser (>= 3.2.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.15.1, < 2.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.24.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.16.0)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.24.1)
parser (>= 3.1.1.0)
rubocop-performance (1.13.2)
rubocop (>= 1.7.0, < 2.0)
Expand All @@ -95,7 +97,7 @@ GEM
slop (3.6.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
unicode-display_width (2.1.0)
unicode-display_width (2.4.2)
values (1.8.0)
webrick (1.7.0)
yard (0.9.28)
Expand All @@ -108,11 +110,11 @@ PLATFORMS
ruby

DEPENDENCIES
dokaz
dokaz (~> 0.0.5)
memo_wise!
panolint!
rake
redcarpet (~> 3.5)
redcarpet (~> 3.6)
rspec (~> 3.11)
simplecov
simplecov-cobertura
Expand Down
42 changes: 21 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,36 +114,36 @@ For more usage details, see our detailed [documentation](#documentation).

Benchmarks are run in GitHub Actions, and the tables below are updated with every code change. **Values >1.00x represent how much _slower_ each gem’s memoized value retrieval is than the latest commit of `MemoWise`**, according to [`benchmark-ips`](https://github.com/evanphx/benchmark-ips) (2.9.2).

Results using Ruby 3.1.2:
Results using Ruby 3.2.1:

|Method arguments|`Dry::Core`\* (0.7.1)|`Memery` (1.4.0)|
|Method arguments|`Dry::Core`\* (1.0.0)|`Memery` (1.4.1)|
|--|--|--|
|`()` (none)|1.14x|13.06x|
|`(a)`|1.22x|7.24x|
|`(a, b)`|1.17x|6.79x|
|`(a:)`|1.33x|16.68x|
|`(a:, b:)`|1.24x|13.73x|
|`(a, b:)`|1.16x|13.58x|
|`(a, *args)`|0.84x|1.95x|
|`(a:, **kwargs)`|0.84x|3.41x|
|`(a, *args, b:, **kwargs)`|0.75x|2.08x|
|`()` (none)|0.55x|3.66x|
|`(a)`|1.55x|8.09x|
|`(a, b)`|1.21x|6.09x|
|`(a:)`|1.42x|13.29x|
|`(a:, b:)`|1.17x|10.04x|
|`(a, b:)`|1.18x|10.32x|
|`(a, *args)`|0.78x|1.54x|
|`(a:, **kwargs)`|0.80x|2.22x|
|`(a, *args, b:, **kwargs)`|0.71x|1.38x|

\* `Dry::Core`
[may cause incorrect behavior caused by hash collisions](https://github.com/dry-rb/dry-core/issues/63).

Results using Ruby 2.7.6 (because these gems raise errors in Ruby 3.x):
Results using Ruby 2.7.7 (because these gems raise errors in Ruby 3.x):

|Method arguments|`DDMemoize` (1.0.0)|`Memoist` (0.16.2)|`Memoized` (1.1.1)|`Memoizer` (1.0.3)|
|--|--|--|--|--|
|`()` (none)|24.72x|2.36x|27.25x|2.88x|
|`(a)`|22.13x|14.22x|23.37x|12.54x|
|`(a, b)`|17.70x|12.04x|17.69x|10.66x|
|`(a:)`|31.24x|24.94x|26.47x|22.97x|
|`(a:, b:)`|25.76x|20.78x|21.41x|19.47x|
|`(a, b:)`|23.97x|19.53x|19.91x|18.01x|
|`(a, *args)`|3.23x|2.21x|3.34x|1.98x|
|`(a:, **kwargs)`|2.92x|2.45x|2.57x|2.24x|
|`(a, *args, b:, **kwargs)`|2.22x|1.88x|1.99x|1.78x|
|`()` (none)|23.65x|2.38x|27.26x|2.71x|
|`(a)`|22.27x|15.66x|22.82x|13.61x|
|`(a, b)`|18.72x|13.85x|18.79x|12.42x|
|`(a:)`|31.54x|25.56x|26.57x|23.88x|
|`(a:, b:)`|27.56x|22.78x|23.67x|21.43x|
|`(a, b:)`|26.16x|21.75x|22.45x|20.63x|
|`(a, *args)`|3.10x|2.32x|3.25x|2.02x|
|`(a:, **kwargs)`|2.82x|2.37x|2.59x|2.23x|
|`(a, *args, b:, **kwargs)`|2.14x|1.84x|1.97x|1.75x|

You can run benchmarks yourself with:

Expand Down
6 changes: 3 additions & 3 deletions benchmarks/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ source "https://rubygems.org"

git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby ">= 2.7.6"
ruby ">= 2.7.7"

gem "benchmark-ips", "2.10.0"

if RUBY_VERSION > "3"
gem "dry-core", "0.7.1"
gem "memery", "1.4.0"
gem "dry-core", "1.0.0"
gem "memery", "1.4.1"
else
gem "ddmemoize", "1.0.0"
gem "memoist", "0.16.2"
Expand Down
13 changes: 7 additions & 6 deletions lib/memo_wise.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "set"
# Disable RuboCop here because Ruby < 3.2 does not load `set` by default.
require "set" # rubocop:disable Lint/RedundantRequireStatement

require "memo_wise/internal_api"
require "memo_wise/version"
Expand Down Expand Up @@ -30,12 +31,12 @@ module MemoWise
# [calling the original](https://medium.com/@jeremy_96642/ruby-method-auditing-using-module-prepend-4f4e69aacd95)
# constructor.
#
# - **Q:** Why is [Module#prepend](https://ruby-doc.org/core-3.1.0/Module.html#method-i-prepend)
# - **Q:** Why is [Module#prepend](https://ruby-doc.org/3.2.1/Module.html#method-i-prepend)
# important here
# ([more info](https://medium.com/@leo_hetsch/ruby-modules-include-vs-prepend-vs-extend-f09837a5b073))?
# - **A:** To set up *mutable state* inside the instance, even if the original
# constructor will then call
# [Object#freeze](https://ruby-doc.org/core-3.1.0/Object.html#method-i-freeze).
# [Object#freeze](https://ruby-doc.org/3.2.1/Object.html#method-i-freeze).
#
# This approach supports memoization on frozen (immutable) objects -- for
# example, classes created by the
Expand Down Expand Up @@ -84,7 +85,7 @@ def initialize(#{all_args})
# @param target [Class]
# The `Class` into to prepend the MemoWise methods e.g. `memo_wise`
#
# @see https://ruby-doc.org/core-3.1.0/Module.html#method-i-prepended
# @see https://ruby-doc.org/3.2.1/Module.html#method-i-prepend
#
# @example
# class Example
Expand All @@ -99,7 +100,7 @@ class << target
#
# This is necessary in addition to the `#initialize` method definition
# above because
# [`Class#allocate`](https://ruby-doc.org/core-3.1.0/Class.html#method-i-allocate)
# [`Class#allocate`](https://ruby-doc.org/3.2.1/Class.html#method-i-allocate)
# bypasses `#initialize`, and when it's used (e.g.,
# [in ActiveRecord](https://github.com/rails/rails/blob/a395c3a6af1e079740e7a28994d77c8baadd2a9d/activerecord/lib/active_record/persistence.rb#L411))
# we still need to be able to access MemoWise's instance variable. Despite
Expand Down Expand Up @@ -254,7 +255,7 @@ def #{method_name}(#{MemoWise::InternalAPI.args_str(method)})
)
end

# Override [Module#instance_method](https://ruby-doc.org/core-3.1.0/Module.html#method-i-instance_method)
# Override [Module#instance_method](https://ruby-doc.org/3.2.1/Module.html#method-i-instance_method)
# to proxy the original `UnboundMethod#parameters` results. We want the
# parameters to reflect the original method in order to support callers
# who want to use Ruby reflection to process the method parameters,
Expand Down
3 changes: 1 addition & 2 deletions spec/memo_wise_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@
end
end

shared_examples "handles memoized/non-memoized methods with the same name at different "\
"scopes" do
shared_examples "handles memoized/non-memoized methods with the same name at different scopes" do
context "with non-memoized method with same name as memoized method" do
context "when methods have no arguments" do
it "does not memoize the non-memoized method" do
Expand Down
6 changes: 3 additions & 3 deletions spec/prepending_initializer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Class.new do
prepend MemoWise

def initialize(arg); end
def initialize(arg); end # rubocop:disable Style/RedundantInitialize
end
end

Expand All @@ -21,7 +21,7 @@ def initialize(arg); end
Class.new do
prepend MemoWise

def initialize(kwarg:); end
def initialize(kwarg:); end # rubocop:disable Style/RedundantInitialize
end
end

Expand All @@ -35,7 +35,7 @@ def initialize(kwarg:); end
Class.new do
prepend MemoWise

def initialize(arg, kwarg:); end
def initialize(arg, kwarg:); end # rubocop:disable Style/RedundantInitialize
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/proxying_original_method_params_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Class.new do
prepend MemoWise

def initialize(foo, bar:); end
def initialize(foo, bar:); end # rubocop:disable Style/RedundantInitialize

DefineMethodsForTestingMemoWise.define_methods_for_testing_memo_wise(
target: self,
Expand Down

0 comments on commit f66db59

Please sign in to comment.