-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Turn on performance based cops #32381
Conversation
r? @schneems (@rails-bot has picked a reviewer for you, use r? to override) |
e847575
to
38c9355
Compare
For the remaining Rubocop errors, one of
Any thoughts on whether to leave these, add ignore comments, or ideas on how to fix? |
155b178
to
0f11c31
Compare
.rubocop.yml
Outdated
@@ -160,3 +160,15 @@ Style/Semicolon: | |||
# Prefer Foo.method over Foo::method | |||
Style/ColonMethodCall: | |||
Enabled: true | |||
|
|||
Style/SymbolProc: | |||
Enabled: true |
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.
Prefer Non Symbol Proc, I think { |timer| timer.shutdown }
it is more readable than (&:shutdown)
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 agree, take this out unless it's also faster. Let's scope this change to only performance.
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.
Benchmark/ips says that they're about the same
require 'benchmark/ips'
array = ["foo", "bar", "baz"]
Benchmark.ips do |x|
x.report("symbol proc ") { array.each(&:upcase) }
x.report("regular proc") { array.each {|x| x.upcase } }
x.compare!
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.
Overall I like the idea. We should remove the Style/SymbolProc:
as it doesn't appear to be faster and makes this change much more noisy.
Also looks like there's some code climate failures.
.rubocop.yml
Outdated
@@ -160,3 +160,15 @@ Style/Semicolon: | |||
# Prefer Foo.method over Foo::method | |||
Style/ColonMethodCall: | |||
Enabled: true | |||
|
|||
Style/SymbolProc: | |||
Enabled: true |
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 agree, take this out unless it's also faster. Let's scope this change to only performance.
.rubocop.yml
Outdated
@@ -160,3 +160,15 @@ Style/Semicolon: | |||
# Prefer Foo.method over Foo::method | |||
Style/ColonMethodCall: | |||
Enabled: true | |||
|
|||
Style/SymbolProc: | |||
Enabled: true |
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.
Benchmark/ips says that they're about the same
require 'benchmark/ips'
array = ["foo", "bar", "baz"]
Benchmark.ips do |x|
x.report("symbol proc ") { array.each(&:upcase) }
x.report("regular proc") { array.each {|x| x.upcase } }
x.compare!
end
.rubocop.yml
Outdated
Style/SymbolProc: | ||
Enabled: true | ||
|
||
Style/TrivialAccessors: |
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.
While it's labeled as "style" this is indeed faster
require 'benchmark/ips'
class Foo
attr_accessor :a
def initialize
@a = "hello"
@b = "world"
end
def b
@b
end
end
foo = Foo.new
Benchmark.ips do |x|
x.report("attr") { foo.a }
x.report("def ") { foo.b }
x.compare!
end
gives
Warming up --------------------------------------
attr 338.812k i/100ms
def 328.549k i/100ms
Calculating -------------------------------------
attr 17.890M (± 3.0%) i/s - 89.446M in 5.004440s
def 15.291M (± 2.5%) i/s - 76.552M in 5.009543s
Comparison:
attr: 17890288.4 i/s
def : 15291283.1 i/s - 1.17x slower
0f11c31
to
0f96701
Compare
Reverted the symbol proc change. Out of the remaining Rubocop errors:
|
r? @matthewd |
@schneems regarding FWIW the benchmark results in https://github.com/JuanitoFatas/fast-ruby#proc--block still hold true on Ruby 2.4.3 and 2.5.0 on my laptop as well. |
I'm in favor of turning the |
@matthewd anything I can do to help get this over the finish line? |
@@ -168,7 +168,8 @@ def url_for(object) | |||
@url_for_options = object | |||
|
|||
if object.is_a?(Hash) && object[:use_route].blank? && object[:controller].blank? | |||
object.merge!(controller: "main", action: "index") | |||
object[:controller] = "main" |
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.
@oniofchaos please use "
only for interpolation
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.
That's the style I use in my own projects but it's not the style for the Rails codebase. You can see the Rubocop failures here: https://codeclimate.com/github/rails/rails/pull/32381
@@ -168,7 +168,8 @@ def url_for(object) | |||
@url_for_options = object | |||
|
|||
if object.is_a?(Hash) && object[:use_route].blank? && object[:controller].blank? | |||
object.merge!(controller: "main", action: "index") | |||
object[:controller] = "main" | |||
object[:action] = "index" |
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.
@oniofchaos same here
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.
@oniofchaos
FYI if you have rubocop gem, you should be warned when writing this, based on following rubocop configuration https://github.com/rails/rails/blob/master/.rubocop.yml#L128
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 enforced style is double_quotes
(docs) so there should be no warning.
Seems fine. Sorry for taking so long. Can you rebase, fix conflicts and I will merge in. Let me know if you don’t know how to do that and need some help. |
654a422
to
9793473
Compare
@schneems fixed! |
Thanks! Looks like codeclimate isn’t happy about a few things. Can you look into those? |
9793473
to
3f39719
Compare
I fixed the 3 |
Can we skip those rules inline? Alternatively, we could get around it with |
3f39719
to
6322693
Compare
Restarting to some failures in railties. Not sure if they're intermittent or not
|
Still failing. |
Use attr_reader/attr_writer instead of methods method is 12% slower Use flat_map over map.flatten(1) flatten is 66% slower Use hash[]= instead of hash.merge! with single arguments merge! is 166% slower See rails#32337 for more conversation
6322693
to
d108288
Compare
Just pushed up a hopeful fix |
I'm not sure how to trigger a rebuild, but it looks like the failure this time was an intermittent issue and not from my code. |
@@ -105,16 +105,20 @@ def make_headers(hash) | |||
end | |||
|
|||
test "#merge! headers with mutation" do | |||
# rubocop:disable Performance/RedundantMerge |
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.
One of the core teams' design goals when adding Rubocop was that we never wanted to add these disable comments. So we've intentionally turned on a light set of cops to give us some enforcement, but not a straitjacket where we'd have to strip the buttons off again.
Let's find another to write this or we just don't enable that cop.
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.
Based on my reading here, it appears this is testing external use of merge!
which we don't have control over. I could rewrite it to use the performance improvement version but it seems to go against the spirit of the test.
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 only other way would be “send”. I think that’s worse than the comment and it’s only in a handful of places.
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 also can turn off Performance/RedundantMerge
for these files via Exclude
in .rubocop.yml
file.
https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md#includingexcluding-files
Going to merge for now. If there is a preferred way for dealing with those rubocop comment exceptions we can update in the future. Thanks for all your work here! |
Follow up of rails/rails#32381. In addition, this PR applies the following auto-correct. ```console % rubocop -a Inspecting 64 files ..........C..................................................... Offenses: spec/active_record/connection_adapters/oracle_enhanced/schema_dumper_spec.rb:22:5: C: [Corrected] Performance/RedundantMerge: Use options[:force] = true instead of options.merge! force: true. options.merge! force: true ^^^^^^^^^^^^^^^^^^^^^^^^^^ 64 files inspected, 1 offense detected, 1 offense corrected ```
Follow up of rails/rails#32381.
Follow up of rails/rails#32381.
PR#32381 added Rubocop's comments to some tests files in order to exclude `Performance/RedundantMerge`. Turn off `Performance` cops for tests files via `Exclude` in `.rubocop.yml`. Context rails#32381 (comment)
Summary
Use attr_reader/attr_writer instead of methods
method is 12% slower
Use flat_map over map.flatten(1)
flatten is 66% slower
Use hash[]= instead of hash.merge! with single arguments
merge! is 166% slower
See #32337 for more conversation