Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add new Performance/DeletePrefix and Performance/DeleteSuffix cops #105

Merged

Conversation

koic
Copy link
Member

@koic koic commented May 6, 2020

This PR adds new Performance/DeletePrefix and Performance/DeleteSuffix cops.

In Ruby 2.5, String#delete_prefix and String#delete_suffix have been added.

Performance/DeletePrefix cop identifies places where gsub(/\Aprefix/, '') can be replaced by delete_prefix('prefix').

# bad
str.gsub(/\Aprefix/, '')
str.gsub!(/\Aprefix/, '')
str.gsub(/^prefix/, '')
str.gsub!(/^prefix/, '')

# good
str.delete_prefix('prefix')
str.delete_prefix!('prefix')

The delete_prefix('prefix') method is faster than gsub(/\Aprefix/, '').

% ruby -v
ruby 2.5.8p224 (2020-03-31 revision 67882) [x86_64-darwin17]

% cat bench.rb
require 'benchmark/ips'

Benchmark.ips do |x|
  str = 'foobar'

  x.report('gsub')           { str.gsub(/bar\z/, '') }
  x.report('gsub!')          { str.gsub(/bar\z/, '') }
  x.report('delete_suffix')  { str.delete_suffix('bar') }
  x.report('delete_suffix!') { str.delete_suffix('bar') }
  x.compare!
end

% ruby bench.rb
Warming up --------------------------------------
                gsub    46.814k i/100ms
               gsub!    46.896k i/100ms
       delete_suffix   211.337k i/100ms
      delete_suffix!   208.332k i/100ms
Calculating -------------------------------------
                gsub    546.500k (± 1.3%) i/s -      2.762M in 5.054918s
               gsub!    551.054k (± 1.2%) i/s -      2.767M in 5.021747s
       delete_suffix      4.780M (± 1.1%) i/s -     24.092M in 5.040850s
      delete_suffix!      4.770M (± 1.1%) i/s -     23.958M in 5.022823s

Comparison:
       delete_suffix:  4780060.8 i/s
      delete_suffix!:  4770419.3 i/s - same-ish: difference falls within error
               gsub!:   551054.2 i/s - 8.67x  slower
                gsub:   546500.1 i/s - 8.75x  slower

Performance/DeleteSuffix cop is the same.


Before submitting the PR make sure the following are checked:

  • Wrote good commit messages.
  • Commit message starts with [Fix #issue-number] (if the related issue exists).
  • Feature branch is up-to-date with master (if not - rebase it).
  • Squashed related commits together.
  • Added tests.
  • Added an entry to the Changelog if the new code introduces user-observable changes. See changelog entry format.
  • The PR relates to only one subject with a clear title
    and description in grammatically correct, complete sentences.
  • Run bundle exec rake default. It executes all tests and RuboCop for itself, and generates the documentation.

@koic koic force-pushed the add_new_delete_prefix_and_delete_suffix_cops branch from 137a66c to c84965c Compare May 6, 2020 18:28
This PR adds new `Performance/DeletePrefix` and `Performance/DeleteSuffix` cops.

In Ruby 2.5, `String#delete_prefix` and `String#delete_suffix` have been added.

- https://ruby-doc.org/core-2.5.8/String.html#method-i-delete_prefix
- https://ruby-doc.org/core-2.5.8/String.html#method-i-delete_suffix

`Performance/DeletePrefix` cop identifies places where `gsub(/\Aprefix/, '')`
can be replaced by `delete_prefix('prefix')`.

```ruby
# bad
str.gsub(/\Aprefix/, '')
str.gsub!(/\Aprefix/, '')
str.gsub(/^prefix/, '')
str.gsub!(/^prefix/, '')

# good
str.delete_prefix('prefix')
str.delete_prefix!('prefix')
```

The `delete_prefix('prefix')` method is faster than `gsub(/\Aprefix/, '')`.

```console
% ruby -v
ruby 2.5.8p224 (2020-03-31 revision 67882) [x86_64-darwin17]

% cat bench.rb
require 'benchmark/ips'

Benchmark.ips do |x|
  str = 'foobar'

  x.report('gsub')           { str.gsub(/bar\z/, '') }
  x.report('gsub!')          { str.gsub(/bar\z/, '') }
  x.report('delete_suffix')  { str.delete_suffix('bar') }
  x.report('delete_suffix!') { str.delete_suffix('bar') }
  x.compare!
end

% ruby bench.rb
Warming up --------------------------------------
                gsub    46.814k i/100ms
               gsub!    46.896k i/100ms
       delete_suffix   211.337k i/100ms
      delete_suffix!   208.332k i/100ms
Calculating -------------------------------------
                gsub    546.500k (± 1.3%) i/s -      2.762M in 5.054918s
               gsub!    551.054k (± 1.2%) i/s -      2.767M in 5.021747s
       delete_suffix      4.780M (± 1.1%) i/s -     24.092M in 5.040850s
      delete_suffix!      4.770M (± 1.1%) i/s -     23.958M in 5.022823s

Comparison:
       delete_suffix:  4780060.8 i/s
      delete_suffix!:  4770419.3 i/s - same-ish: difference falls within error
               gsub!:   551054.2 i/s - 8.67x  slower
                gsub:   546500.1 i/s - 8.75x  slower
```

`Performance/DeleteSuffix` cop is the same.
@koic koic force-pushed the add_new_delete_prefix_and_delete_suffix_cops branch from c84965c to 78047b0 Compare May 6, 2020 18:54
@koic koic merged commit 0f14f80 into rubocop:master May 10, 2020
@koic koic deleted the add_new_delete_prefix_and_delete_suffix_cops branch May 10, 2020 23:34
@vishalzambre
Copy link

@koic delete_prefix doesn't support to regex but rubocop gives error if gsub is used with regex

@koic
Copy link
Member Author

koic commented Jun 19, 2020

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants