-
-
Notifications
You must be signed in to change notification settings - Fork 640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix breaking change introduced in https://github.com/CanCanCommunity/cancancan/pull/204 #571
Closed
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
e5dc5eb
to
e73e95d
Compare
coorasse
approved these changes
Mar 16, 2019
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job! Thank you!
@coorasse Is there anything to do I can help to move this PR forward? |
could you please fix the CI? this would speed things up. Thank you |
context: CanCanCommunity#204 (comment) `Kernel.#Array` calls not only `Object#to_ary` but also `Object#to_a` but some classes which represent cluster may implement `to_a`. https://api.rubyonrails.org/classes/Array.html#method-c-wrap I think that's why ActiveSupport has `Array.wrap`. https://api.rubyonrails.org/classes/Array.html#method-c-wrap I confirmed there's no performance regression via the following snippet: ```ruby require "bundler/inline" gemfile(true) do source "https://rubygems.org" gem "benchmark-ips", "2.7.2" gem "cancancan", "2.3.0" gem "allocation_tracer", "0.6.3" end module CanCan class Rule def initialize(base_behavior, action, subject, conditions, block, __flag__:) both_block_and_hash_error = 'You are not able to supply a block with a hash of conditions in '\ "#{action} #{subject} ability. Use either one." raise Error, both_block_and_hash_error if conditions.is_a?(Hash) && block @match_all = action.nil? && subject.nil? @base_behavior = base_behavior case __flag__ when :array @actions = Array(action) @subjects = Array(subject) when :flatten @actions = [action].flatten @subjects = [subject].flatten when :wrap @actions = wrap(action) @subjects = wrap(subject) else raise end @conditions = conditions || {} @block = block end def wrap(object) if object.nil? [] elsif object.respond_to?(:to_ary) object.to_ary || [object] else [object] end end end end def memprof(name) GC.disable before = `ps -o rss -p #{Process.pid}`.split("\n").last.to_i ObjectSpace::AllocationTracer.trace do 10_000.times do yield end end after = `ps -o rss -p #{Process.pid}`.split("\n").last.to_i puts "[#{name}] Mem diff: #{(after - before).to_f/1024.0} MB" GC.enable GC.start end puts "Ruby #{RUBY_VERSION}" # I think memprof outputs wrong result because always first one gets the worst result # I just followed original one # https://gist.github.com/timraymond/8d7014e0c7804f0fe508 memprof("Kernel.#Array") { CanCan::Rule.new(nil, [:read, :write], [:foo, :bar], nil, nil, __flag__: :array) } memprof("Array#flatten") { CanCan::Rule.new(nil, [:read, :write], [:foo, :bar], nil, nil, __flag__: :flatten) } memprof("Array.wrap") { CanCan::Rule.new(nil, [:read, :write], [:foo, :bar], nil, nil, __flag__: :wrap) } Benchmark.ips do |b| b.report("Kernel.#Array") { CanCan::Rule.new(nil, [:read, :write], [:foo, :bar], nil, nil, __flag__: :array) } b.report("Array#flatten") { CanCan::Rule.new(nil, [:read, :write], [:foo, :bar], nil, nil, __flag__: :flatten) } b.report("Array.wrap") { CanCan::Rule.new(nil, [:read, :write], [:foo, :bar], nil, nil, __flag__: :wrap) } b.compare! end __END__ Ruby 2.6.1 [Kernel.#Array] Mem diff: 21.59765625 MB [Array#flatten] Mem diff: 2.21484375 MB [Array.wrap] Mem diff: 0.02734375 MB Warming up -------------------------------------- Kernel.#Array 5.024k i/100ms Array#flatten 3.863k i/100ms Array.wrap 5.217k i/100ms Calculating ------------------------------------- Kernel.#Array 204.954k (±21.6%) i/s - 964.608k in 5.003037s Array#flatten 143.892k (±17.3%) i/s - 695.340k in 5.005342s Array.wrap 195.569k (±18.5%) i/s - 933.843k in 5.003945s Comparison: Kernel.#Array: 204954.3 i/s Array.wrap: 195569.0 i/s - same-ish: difference falls within error Array#flatten: 143892.4 i/s - same-ish: difference falls within error Ruby 2.5.3 [Kernel.#Array] Mem diff: 21.98046875 MB [Array#flatten] Mem diff: 0.93359375 MB [Array.wrap] Mem diff: 0.0 MB Warming up -------------------------------------- Kernel.#Array 4.816k i/100ms Array#flatten 4.235k i/100ms Array.wrap 4.610k i/100ms Calculating ------------------------------------- Kernel.#Array 166.440k (±30.7%) i/s - 722.400k in 5.010362s Array#flatten 136.055k (±23.3%) i/s - 639.485k in 5.009729s Array.wrap 173.409k (±18.6%) i/s - 820.580k in 5.019846s Comparison: Array.wrap: 173408.7 i/s Kernel.#Array: 166439.5 i/s - same-ish: difference falls within error Array#flatten: 136054.8 i/s - same-ish: difference falls within error Ruby 2.4.5 [Kernel.#Array] Mem diff: 17.0859375 MB [Array#flatten] Mem diff: 0.0234375 MB [Array.wrap] Mem diff: 0.0 MB Warming up -------------------------------------- Kernel.#Array 4.746k i/100ms Array#flatten 4.019k i/100ms Array.wrap 4.347k i/100ms Calculating ------------------------------------- Kernel.#Array 195.099k (±17.4%) i/s - 939.708k in 4.994105s Array#flatten 117.881k (±19.3%) i/s - 562.660k in 5.012299s Array.wrap 160.679k (±13.9%) i/s - 782.460k in 5.005515s Comparison: Kernel.#Array: 195099.4 i/s Array.wrap: 160678.6 i/s - same-ish: difference falls within error Array#flatten: 117881.1 i/s - 1.66x slower ```
d290dc2
to
1d89180
Compare
Merged in #614 . Thank you! |
@coorasse Sorry I overlooked response from you 🙇 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
context: #204 (comment)
Kernel.#Array
calls not onlyObject#to_ary
but alsoObject#to_a
but some classes which represent cluster may implementto_a
.https://api.rubyonrails.org/classes/Array.html#method-c-wrap
I think that's why ActiveSupport has
Array.wrap
.https://api.rubyonrails.org/classes/Array.html#method-c-wrap
I confirmed there's no performance regression via the following snippet: