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
Performance. RSpec/LetSetup #951
Performance. RSpec/LetSetup #951
Conversation
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.
Those def_node_search
es seem to be the root of all evil.
Thanks! Performance combo 🤜 👊 🤛 🤜
1fe0377
to
af294ae
Compare
lib/rubocop/cop/rspec/let_setup.rb
Outdated
def child_let_bang(block_node) | ||
return unless block_node.body&.begin_type? | ||
|
||
block_node.body.each_child_node(:block) do |child| |
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.
It would be great if you could yield
if the passed block yielded, e.g. if there is shorter or more FP way to write the code below
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.
Do you mean something like this?
block_node.body.each_child_node(:block)
.map { |child| let_bang(child) }
.reject { |m| m.nil? }
.each { |m| yield m }
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, or
block_node.body.each_child_node(:block)
.map(&method(:let_bang)
.compact
.each { |m| yield m }
But would prefer to have it even shorter, or at least without having to use explicit blocks
Ideally something like
block_node.body.each_child_node(:block).yield_when(&method(:let_bang)
Anyway, that was just a side note, as I hate to see things like
a = something
yield a if a
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.
Sorry, I've missed that this has been discussed already.
Compared generated offenses with |
e909801
to
9072de8
Compare
lib/rubocop/cop/rspec/let_setup.rb
Outdated
|
||
def unwrap_nested_begin(node) | ||
node.body.begin_type? ? node.body : node | ||
end |
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.
Just realized the whole implementation of child_let_bang
could be replaced with RuboCop::RSpec::ExampleGroup
:
RuboCop::RSpec::ExampleGroup.new(node).lets.map { |let| let_bang(let) }.compact
https://github.com/rubocop-hq/rubocop-rspec/blob/master/lib/rubocop/rspec/example_group.rb
I am wondering whether it makes sense to check this approach.
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.
Absolutely. Those helpers keep being under the radar.
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.
Done. Looks pretty good.
1821389
to
28660a7
Compare
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.
Perfect! <3
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.
Good job. I added just a single comment.
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.
🚀
Please squash the commits |
08e9033
to
28eab5a
Compare
Done |
Awesome perf-combo! 💯 Thanks a lot. |
Optimize RSpec/LetSetup cop and #on_block callback.
Changes
let!
nodes nested into current example groupThe approach is to iterate over only direct child
let!
nodes of a current example group.Performance measurements
Timing for RuboCop::Cop::RSpec::LetSetup#on_block is changed from 10.2% to 1.3%.
Before
After
Measurements approach
Used
stackprof
profiler to measure proportion of the cop timing. Running Rubocop on the GitLab project specs.Run only one cope without caching and skip config with command
Before submitting the PR make sure the following are checked:
master
(if not - rebase it).CHANGELOG.md
if the new code introduces user-observable changes.bundle exec rake
) passes (be sure to run this locally, since it may produce updated documentation that you will need to commit).