-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Add Performance/Caller
cop
#4078
Conversation
f21dbe2
to
a16fe1c
Compare
Performance/CallerLocations
copPerformance/CallerLocations
cop
config/enabled.yml
Outdated
@@ -1342,6 +1342,11 @@ Lint/Void: | |||
|
|||
#################### Performance ########################### | |||
|
|||
Performance/CallerLocations: | |||
Description: >- | |||
Use `caller_locations` instance of `caller` |
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.
Did you mean instead of? 🙂
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.
ooops... 😇
SCOPE_METHODS = [:first, :[]].freeze | ||
|
||
def on_send(node) | ||
add_offense(node, node.loc.selector, MSG) if unneeded_caller?(node) |
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.
There should be a shortcut that allows you to do this:
add_offense(node, :selector)
|
||
it 'registers an offense when :[] is called on caller' do | ||
inspect_source(cop, 'caller[0]') | ||
expect(cop.messages).to eq([described_class::MSG]) |
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.
We would normally assert:
expect(cop.offenses.size).to eq(1)
Asserting messages is generally only done for cops that have messages that change depending on context. 🙂
a16fe1c
to
98d1b92
Compare
|
||
require 'spec_helper' | ||
|
||
fdescribe RuboCop::Cop::Performance::CallerLocations do |
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.
fdescribe
This look like filter option.
If are you using filter option in development, you have to remove after development.
567bc03
to
7f9969f
Compare
Some more background on this would be useful as the replacement code seems way more complex than the straightforward "slow" code. |
4d82fe4
to
017d495
Compare
Performance/CallerLocations
copPerformance/Caller
cop
@bbatsov I fixed to simply replace with @dorian Thank you for reviewing 👍
hmm, could you tell me more details to what should i fix? 🤔 |
Just two more things:
|
Btw, shouldn't this cop be more generic? If you do |
Any progress here? If not - I'll be forced to close this due to lack of activity. |
Sorry, I kept you waiting. I am trying to improve this pr 🙏 |
Just adding a bit more bench-marking information because I was curious. [14] pry(main)> Benchmark.ips do |x|
[14] pry(main)* x.report('caller.first') { caller.first }
[14] pry(main)* x.report('caller(1..1).first') { caller(1..1).first }
[14] pry(main)* x.compare!
[14] pry(main)* end
Warming up --------------------------------------
caller.first 2.314k i/100ms
caller(1..1).first 36.661k i/100ms
Calculating -------------------------------------
caller.first 24.241k (±13.5%) i/s - 120.328k in 5.055955s
caller(1..1).first 490.166k (±16.5%) i/s - 2.383M in 5.028717s
Comparison:
caller(1..1).first: 490166.1 i/s
caller.first: 24240.7 i/s - 20.22x slower Most of the ideas for our performance cops came from fast-ruby. I didn't see this one listed. It might be nice to make a PR against their project as well. |
f278d42
to
c6ff058
Compare
@bbatsov Fixed 👍 |
@alpaca-tc You have to rebase and resolve conflicts. |
c6ff058
to
d719732
Compare
The messages at least still mention |
arguments = node.receiver.arguments | ||
|
||
arguments.empty? || | ||
(arguments.length == 1 && arguments[0].type == :int) |
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.
Should this check arguments[0].int_type?
instead of arguments[0].type == :int
?
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.
Yes.
d719732
to
d84889b
Compare
8eae5ab
to
1499416
Compare
You should rebase this on top of the current |
# caller(n..n).first | ||
# caller(1..1).first | ||
class Caller < Cop | ||
MSG = 'Use `caller(n..n)` instead of `caller`.'.freeze |
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.
I guess instead of caller[n]
would be more clear here.
1499416
to
6ebd132
Compare
6ebd132
to
f93009e
Compare
@alpaca-tc how come this suggests |
@aripollak yeah, it sounds nice |
I too noticed that the message could use some clarification. "Use |
Example
Benchmark
Before submitting the PR make sure the following are checked:
[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).and description in grammatically correct, complete sentences.
rake generate_cops_documentation
(required only when you've added a new cop or changed the configuration/documentation of an existing cop).