Skip to content
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

Replace checking start/end of string #17316

Closed
wants to merge 1 commit into from

Conversation

@igas
Copy link
Contributor

commented Oct 19, 2014

Replace =~ /^str/, =~ /str$/, !~ /^str/, and !~ /str$/ to start_with? and end_with? when possible. Mostly it's 1,6x faster, some more impressive benchmarks:

actionpack/lib/abstract_controller/helpers.rb:

Benchmark.ips do |x|
  x.report('=~') { error.path =~ /^#{path}(\.rb)?$/ }
  x.report('start/end') { error.path.start_with?(path) && error.path.end_with?('.rb', '') }
  x.compare!
end
Calculating -------------------------------------
                  =~      7097 i/100ms
           start/end     29688 i/100ms
-------------------------------------------------
                  =~   104752.3 (±8.3%) i/s -     525178 in   5.049548s
           start/end  2423935.7 (±10.8%) i/s -   11964264 in   5.003489s

Comparison:
           start/end:  2423935.7 i/s
                  =~:   104752.3 i/s - 23.14x slower

actionpack/lib/action_dispatch/journey/visitors.rb:

Benchmark.ips do |x|
  x.report('=~') do
    next unless pim =~ /^visit_(.*)$/
    DISPATCH_CACHE[$1.to_sym] = pim
  end
  x.report('start/end') do
    next unless pim.to_s.start_with?('visit_')
    DISPATCH_CACHE[pim[/^visit_(.*)$/, 1].to_sym] = pim
  end
  x.compare!
end
Calculating -------------------------------------
                  =~     58993 i/100ms
           start/end     73946 i/100ms
-------------------------------------------------
                  =~  1832025.8 (±6.6%) i/s -    9143915 in   5.012602s
           start/end  2944646.4 (±8.2%) i/s -   14641308 in   5.006457s

Comparison:
           start/end:  2944646.4 i/s
                  =~:  1832025.8 i/s - 1.61x slower

actionview/lib/action_view/helpers/asset_tag_helper.rb:

Benchmark.ips do |x|
  x.report('=~') { src =~ /^(?:cid|data):/ }
  x.report('start/end') { src.start_with?('cid:', 'data:') }
  x.compare!
end
Calculating -------------------------------------
                  =~     26869 i/100ms
           start/end     29965 i/100ms
-------------------------------------------------
                  =~  1853626.9 (±8.5%) i/s -    9189198 in   4.996903s
           start/end  2894114.5 (±13.0%) i/s -   14173445 in   4.993368s

Comparison:
           start/end:  2894114.5 i/s
                  =~:  1853626.9 i/s - 1.56x slower

actionview/lib/action_view/renderer/template_renderer.rb:

Benchmark.ips do |x|
  x.report('=~') { layout =~ /^\// }
  x.report('start/end') { layout.start_with?('/') }
  x.compare!
end
Calculating -------------------------------------
                  =~     25597 i/100ms
           start/end     33362 i/100ms
-------------------------------------------------
                  =~  1451851.0 (±9.4%) i/s -    7192757 in   5.000724s
           start/end  4360476.8 (±14.0%) i/s -   21251594 in   4.996049s

Comparison:
           start/end:  4360476.8 i/s
                  =~:  1451851.0 i/s - 3.00x slower

activesupport/lib/active_support/multibyte/chars.rb:

Benchmark.ips do |x|
  x.report('=~') { method.to_s =~ /!$/ }
  x.report('start/end') { method.to_s.end_with?('!') }
  x.compare!
end
Calculating -------------------------------------
                  =~     25899 i/100ms
           start/end     30125 i/100ms
-------------------------------------------------
                  =~  2046233.9 (±9.2%) i/s -   10126509 in   4.998104s
           start/end  3313337.1 (±12.0%) i/s -   16267500 in   4.994593s

Comparison:
           start/end:  3313337.1 i/s
                  =~:  2046233.9 i/s - 1.62x slower
@env.delete_if do |k, _|
k.start_with?('action_dispatch.request', 'rack.request')
end
@env.delete_if { |k, _| k.start_with?('action_dispatch.rescue') }

This comment has been minimized.

Copy link
@egilburg

egilburg Oct 19, 2014

Contributor

can these 2 statements be combined?
k.start_with?('action_dispatch.request', 'rack.request', 'action_dispatch.rescue')

@@ -301,7 +301,7 @@ def app_const
end

def valid_const?
if app_const =~ /^\d/
if app_const.start_with?("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")

This comment has been minimized.

Copy link
@egilburg

egilburg Oct 19, 2014

Contributor

imo this change isn't worth it readability wise, particularly as app generator isn't a hotspot

@@ -329,7 +329,7 @@ def email
def valid_const?
if original_name =~ /[^0-9a-zA-Z_]+/
raise Error, "Invalid plugin name #{original_name}. Please give a name which use only alphabetic or numeric or \"_\" characters."
elsif camelized =~ /^\d/
elsif camelized.start_with?("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")

This comment has been minimized.

Copy link
@egilburg

egilburg Oct 19, 2014

Contributor

same as above regarding readability

@@ -18,7 +18,7 @@ def initialize(error, path)
@path = "helpers/#{path}.rb"
set_backtrace error.backtrace

if error.path =~ /^#{path}(\.rb)?$/
if error.path.start_with?(path) && error.path.end_with?('.rb', '')

This comment has been minimized.

Copy link
@egilburg

egilburg Oct 19, 2014

Contributor

what does the '' argument accomplish here? what's the meaning of checking if a string "ends with" a blank string?

next unless pim =~ /^visit_(.*)$/
DISPATCH_CACHE[$1.to_sym] = pim
next unless pim.to_s.start_with?('visit_')
DISPATCH_CACHE[pim[/^visit_(.*)$/, 1].to_sym] = pim

This comment has been minimized.

Copy link
@egilburg

egilburg Oct 19, 2014

Contributor

not sure this change is worth it as you end up constructing regex anyways

@matthewd

This comment has been minimized.

Copy link
Member

commented Oct 19, 2014

👎 I see at least two that are just wrong, most seem uglier, and hardly any are in places where the perf difference could ever matter.

@rafaelfranca

This comment has been minimized.

Copy link
Member

commented Oct 19, 2014

Agree with @matthewd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.