Skip to content

Include unnecessary blocks in affix checks #516

@dduugg

Description

@dduugg

Is your feature request related to a problem? Please describe.

Performance/DoubleStartEndWith already exists to flag repeated calls to start_with?/end_with? that could be replaced by a single call. Another pattern involving excess affix checks is:

prefixes.any? { |prefix| str.start_with?(prefix) }

which is less performant and less readable than the varargs version:

str.start_with?(*prefixes)

Benchmark code:

require 'benchmark/ips'

prefixes = 100.times.map { ('a'..'z').to_a.shuffle[0,8].join }
str =  ('a'..'z').to_a.shuffle[0,20].join

Benchmark.ips do |x|
  x.report('block') { prefixes.any? { |prefix| str.start_with?(prefix) } }
  x.report('varargs') { str.start_with?(*prefixes) }
  x.compare!
end

Results:

Warming up --------------------------------------
               block    24.496k i/100ms
             varargs   104.671k i/100ms
Calculating -------------------------------------
               block    247.547k (± 0.8%) i/s    (4.04 μs/i) -      1.249M in   5.047027s
             varargs      1.053M (± 0.8%) i/s  (949.67 ns/i) -      5.338M in   5.069843s

Comparison:
             varargs:  1053000.4 i/s
               block:   247547.4 i/s - 4.25x  slower

Describe the solution you'd like

A new cop (or an expansion to DoubleStartEndWith) that flags start_with?/end_with? called inside an any? block.

Describe alternatives you've considered

🤔

Additional context

https://github.com/Homebrew/brew/pull/20612/files has examples that were manually corrected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions