Skip to content

Instantly share code, notes, and snippets.

@pixeltrix
Last active November 23, 2018 07:32
Show Gist options
  • Save pixeltrix/8261957 to your computer and use it in GitHub Desktop.
Save pixeltrix/8261957 to your computer and use it in GitHub Desktop.
Benchmark of changing optimized route generation to pre-splitting the route versus using gsub with a complex route
require 'benchmark/ips'
require 'action_controller/railtie'
ROUTE = '/posts/:post_id/comments/:id.:format'
PARTS = [:post_id, :id, :format]
OPTIMIZED = ["/", "posts", "/", :post_id, "/", "comments", "/", :id, ".", :format]
KLASS = ActionDispatch::Journey::Router::Utils
def optimized_helper_1(*args)
path = ROUTE.dup
klass = ActionDispatch::Journey::Router::Utils
PARTS.zip(args) do |part, arg|
parameterized_arg = arg.to_param
if parameterized_arg.nil? || parameterized_arg.empty?
raise ActionController::UrlGenerationError
end
path.gsub!(/(\*|:)#{part}/, klass.escape_fragment(parameterized_arg))
end
path
end
def optimized_helper_2(*args)
params = Hash[parameterize_args(args)]
missing = missing_keys(params)
unless missing.empty?
raise ActionController::UrlGenerationError
end
OPTIMIZED.map{ |segment| replace_segment(params, segment) }.join
end
def replace_segment(params, segment)
Symbol === segment ? KLASS.escape_fragment(params[segment]) : segment
end
def parameterize_args(args)
[].tap do |parameterized_args|
PARTS.zip(args) do |part, arg|
parameterized_arg = arg.to_param
parameterized_args << [part, parameterized_arg]
end
end
end
def missing_keys(args)
args.select{ |part, arg| arg.nil? || arg.empty? }.keys
end
Benchmark.ips do |x|
x.report('Current Helper: ') { optimized_helper_1(2, 1, :json) }
x.report('New Helper: ') { optimized_helper_2(2, 1, :json) }
end
Calculating -------------------------------------
Current Helper: 2367 i/100ms
New Helper: 5382 i/100ms
-------------------------------------------------
Current Helper: 29506.0 (±3.2%) i/s - 149121 in 5.059294s
New Helper: 78815.5 (±4.1%) i/s - 398268 in 5.062161s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment