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
Quick performance review #8022
Comments
Great initiative! I have to admit that lately we haven't paid as much attention to performance as we should have. Looking at the list of offenders it seems a lot of them are space-related (and probably implemented in a similar fashion). |
I've run Rubocop with profiler (stackprof) on a large Rails application (proprietary) and received a little bit different top 10 list: CLICK MEstackprof tmp/stackprof-cpu.dump --text --sort-total --limit 150 | grep RuboCop::Cop 1772 (6.8%) 0 (0.0%) RuboCop::Cop::Layout::SpaceInsideReferenceBrackets#on_send 971 (3.7%) 0 (0.0%) RuboCop::Cop::Style::TrailingMethodEndStatement#trailing_end? 971 (3.7%) 0 (0.0%) RuboCop::Cop::Style::TrailingMethodEndStatement#on_def 969 (3.7%) 0 (0.0%) RuboCop::Cop::Style::TrailingMethodEndStatement#body_and_end_on_same_line? 966 (3.7%) 2 (0.0%) RuboCop::Cop::Style::TrailingMethodEndStatement#end_token 374 (1.4%) 0 (0.0%) RuboCop::Cop::Layout::SpaceInsideArrayLiteralBrackets#on_array 357 (1.4%) 1 (0.0%) RuboCop::Cop::Layout::IndentationWidth#check_indentation 353 (1.3%) 0 (0.0%) RuboCop::Cop::Layout::SpaceInsideArrayLiteralBrackets#array_brackets 352 (1.3%) 0 (0.0%) RuboCop::Cop::Layout::SpaceInsideArrayLiteralBrackets#left_array_bracket 327 (1.2%) 0 (0.0%) RuboCop::Cop::Layout::IndentationWidth#check_members 315 (1.2%) 0 (0.0%) RuboCop::Cop::Layout::SpaceInsideHashLiteralBraces#hash_literal_with_braces 315 (1.2%) 0 (0.0%) RuboCop::Cop::Layout::SpaceInsideHashLiteralBraces#on_hash 294 (1.1%) 0 (0.0%) RuboCop::Cop::RangeHelp#column_offset_between 294 (1.1%) 281 (1.1%) RuboCop::Cop::RangeHelp#effective_column 294 (1.1%) 140 (0.5%) RuboCop::Cop::Style::RedundantSelf#add_scope 278 (1.1%) 0 (0.0%) RuboCop::Cop::Layout::IndentationWidth#on_class 277 (1.1%) 0 (0.0%) RuboCop::Cop::Layout::IndentationWidth#check_members_for_normal_style 251 (1.0%) 2 (0.0%) RuboCop::Cop::Layout::EmptyLines#investigate 247 (0.9%) 0 (0.0%) RuboCop::Cop::Layout::EndAlignment#check_other_alignment 242 (0.9%) 194 (0.7%) RuboCop::Cop::Badge#to_s 235 (0.9%) 7 (0.0%) RuboCop::Cop::Style::NumericPredicate#on_send 231 (0.9%) 0 (0.0%) RuboCop::Cop::Layout::IndentationConsistency#check 229 (0.9%) 0 (0.0%) RuboCop::Cop::Layout::IndentationConsistency#on_begin 219 (0.8%) 1 (0.0%) RuboCop::Cop::Layout::IndentationConsistency#check_normal_style 216 (0.8%) 0 (0.0%) RuboCop::Cop::Layout::SpaceBeforeFirstArg#on_send 207 (0.8%) 0 (0.0%) RuboCop::Cop::RangeHelp#column_offset_between So it's definitely makes sense to have some performance testing methodology - e.g. to choose some large public Ruby codebases and measure performance improvements against them. I wouldn't say the Rubocop source code is either typical or large. |
Super interesting @andrykonchin The listing I gave was with If the Still, many cops are showing in both reports... |
Thank you. It's very helpful. I profiled rubocop on the whole my project (earlier I ran it only on a subdirectory
I'm exited to play with performance issues and testing so going to choose several Ruby/Rails projects and analyze them with stackprof. I am wondering whether it makes sense to use another sampling profiler or even tracing one? |
If you're looking for a good size non-Rails ruby project to test rubocop with: https://github.com/chef/chef |
Just for the record. I've profiled rubocop-rspec cops and fixed most not efficient ones:
|
Great! I was wondering about the best way to be able to do profiling. I'm not super happy about #8242, comments welcome. @andrykonchin were some of these cops using tokens? I was looking at |
No. The common issue is excessive recursion and usage of
Yeah, micro optimizations will not help much here. These inefficient cops should be rethought and rewritten. Hope I will be able to try after a short break. |
Does profiling against a large project make sense? Is the output reporting how long a single cop took when running one-time, or do cops bubble to the top because they are fully executed more than other cops? |
Yes, but a small project works too. The latter. We have some builtin tools now btw. |
@marcandre - is there a standard "small project" that you've been using for profiling? |
I've been using |
I had fun checking what takes time when inspecting RuboCop's own files.
Once I excluded the worst offender (see #8021), here's the top 20:
The fastest cops take 0.0%, so there's potential for improvement.
First comes
RuboCop::Cop::Layout::SpaceInsideArrayLiteralBrackets
. It usestokens
which should probably be optimized (e.g. usingbsearch_index
), but I'm not sure it should even be looking at tokens at all.Second comes
RuboCop::Cop::Style::RedundantSelf
. Much more involved because it keeps tracks of scopes, but it should probably useVariableForce
, no?The fact that
RuboCop::Cop::RSpec::FactoryBot::AttributeDefinedStatically
is in the top 20 when the whole source code of Rubocop doesn't useFactoryBot
is alarming...I'll create a PR to add some profiling capacity
The text was updated successfully, but these errors were encountered: