-
-
Notifications
You must be signed in to change notification settings - Fork 83
Change Performance/CollectionLiteralInLoop
to not register offenses for Array#include?
that are optimized directly in Ruby.
#488
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
Conversation
🤔 how do I get the oldest rubocop version tests to pass when it doesn't know about |
a07c8e5
to
735f8b5
Compare
I just added it manually for now, can be removed when the minimum supported rubocop gets bumped. |
].each do |argument| | ||
it "registers no offense when the argument is #{argument}" do | ||
expect_no_offenses(<<~RUBY) | ||
#{'local_variable = 123' if argument == 'local_variable'} |
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.
The presence or absence of this string interpolation does not change the testing result, but is this code meaningful in relation to the test's behavior?
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.
Removing it makes it send instead of lvar, but both are handled so the test doesn't visibly change
|
||
context 'when Ruby >= 3.4', :ruby34 do | ||
# TODO: Remove when the minimum supported RuboCop is 1.62.0 | ||
let(:ruby_version) { 3.4 } |
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.
The current latest version of RuboCop Performance already requires RuboCop 1.72+. Can you remove it?
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, I removed it
… register offenses for `Array#include?` that are optimized directly in Ruby. Since `include?` on arrays are the only instances I ever run across this cop, I think it makes sense to add special handling for this. On Ruby 3.4 this does no array allocations: ``` require "memory_profiler" class Foo def bar Bar.new end end class Bar def baz end end foo = Foo.new report = MemoryProfiler.report do [1,2].include?(foo.bar.baz) end.pretty_print ``` Also, this code is simply slower on Ruby 3.4: ```rb require "benchmark/ips" local = [301, 302] val = 301 Benchmark.ips do |x| x.report('local') do local.include?(val) end x.report('literal') do [301, 302].include?(val) end x.compare! end ``` ``` $ ruby test.rb ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] Warming up -------------------------------------- local 1.822M i/100ms literal 2.296M i/100ms Calculating ------------------------------------- local 18.235M (± 1.6%) i/s (54.84 ns/i) - 92.906M in 5.096277s literal 22.807M (± 1.5%) i/s (43.85 ns/i) - 114.789M in 5.034289s Comparison: literal: 22806932.0 i/s local: 18235340.7 i/s - 1.25x slower ```
735f8b5
to
d196b53
Compare
Thanks! |
Fix #482. Since
include?
on arrays are the only instances I ever run across this cop, I think it makes sense to add special handling for this.On Ruby 3.4 this does no array allocations:
Also, this code is simply slower on Ruby 3.4:
Before submitting the PR make sure the following are checked:
[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).bundle exec rake default
. It executes all tests and runs RuboCop on its own code.{change_type}_{change_description}.md
if the new code introduces user-observable changes. See changelog entry format for details.