Skip to content

Commit

Permalink
Merge pull request #42779 from jhawthorn/faster_template_lookups
Browse files Browse the repository at this point in the history
Speed up template lookups by avoiding splats and ===
  • Loading branch information
jhawthorn committed Jul 14, 2021
2 parents c9cdf74 + d4ca317 commit e70b0a4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 28 deletions.
28 changes: 12 additions & 16 deletions actionview/lib/action_view/lookup_context.rb
Expand Up @@ -122,21 +122,29 @@ module ViewPaths
attr_reader :view_paths, :html_fallback_for_js

def find(name, prefixes = [], partial = false, keys = [], options = {})
@view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options))
name, prefixes = normalize_name(name, prefixes)
details, details_key = detail_args_for(options)
@view_paths.find(name, prefixes, partial, details, details_key, keys)
end
alias :find_template :find

def find_all(name, prefixes = [], partial = false, keys = [], options = {})
@view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys, options))
name, prefixes = normalize_name(name, prefixes)
details, details_key = detail_args_for(options)
@view_paths.find_all(name, prefixes, partial, details, details_key, keys)
end

def exists?(name, prefixes = [], partial = false, keys = [], **options)
@view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))
name, prefixes = normalize_name(name, prefixes)
details, details_key = detail_args_for(options)
@view_paths.exists?(name, prefixes, partial, details, details_key, keys)
end
alias :template_exists? :exists?

def any?(name, prefixes = [], partial = false)
@view_paths.exists?(*args_for_any(name, prefixes, partial))
name, prefixes = normalize_name(name, prefixes)
details, details_key = detail_args_for_any
@view_paths.exists?(name, prefixes, partial, details, details_key, [])
end
alias :any_templates? :any?

Expand All @@ -147,12 +155,6 @@ def build_view_paths(paths)
ActionView::PathSet.new(Array(paths))
end

def args_for_lookup(name, prefixes, partial, keys, details_options)
name, prefixes = normalize_name(name, prefixes)
details, details_key = detail_args_for(details_options)
[name, prefixes, partial || false, details, details_key, keys]
end

# Compute details hash and key according to user options (e.g. passed from #render).
def detail_args_for(options) # :doc:
return @details, details_key if options.empty? # most common path.
Expand All @@ -167,12 +169,6 @@ def detail_args_for(options) # :doc:
[user_details, details_key]
end

def args_for_any(name, prefixes, partial)
name, prefixes = normalize_name(name, prefixes)
details, details_key = detail_args_for_any
[name, prefixes, partial || false, details, details_key]
end

def detail_args_for_any
@detail_args_for_any ||= begin
details = {}
Expand Down
25 changes: 14 additions & 11 deletions actionview/lib/action_view/path_set.rb
Expand Up @@ -44,28 +44,31 @@ def #{method}(*args)
METHOD
end

def find(*args)
find_all(*args).first || raise(MissingTemplate.new(self, *args))
def find(path, prefixes, partial, details, details_key, locals)
find_all(path, prefixes, partial, details, details_key, locals).first ||
raise(MissingTemplate.new(self, path, prefixes, partial, details, details_key, locals))
end

def find_all(path, prefixes = [], *args)
_find_all path, prefixes, args
def find_all(path, prefixes, partial, details, details_key, locals)
search_combinations(prefixes) do |resolver, prefix|
templates = resolver.find_all(path, prefix, partial, details, details_key, locals)
return templates unless templates.empty?
end
[]
end

def exists?(path, prefixes, *args)
find_all(path, prefixes, *args).any?
def exists?(path, prefixes, partial, details, details_key, locals)
find_all(path, prefixes, partial, details, details_key, locals).any?
end

private
def _find_all(path, prefixes, args)
prefixes = [prefixes] if String === prefixes
def search_combinations(prefixes)
prefixes = Array(prefixes)
prefixes.each do |prefix|
paths.each do |resolver|
templates = resolver.find_all(path, prefix, *args)
return templates unless templates.empty?
yield resolver, prefix
end
end
[]
end

def typecast(paths)
Expand Down
2 changes: 1 addition & 1 deletion actionview/test/template/lookup_context_test.rb
Expand Up @@ -221,7 +221,7 @@ def setup
test "if a single prefix is passed as a string and the lookup fails, MissingTemplate accepts it" do
e = assert_raise ActionView::MissingTemplate do
details = { handlers: [], formats: [], variants: [], locale: [] }
@lookup_context.view_paths.find("foo", "parent", true, details)
@lookup_context.view_paths.find("foo", "parent", true, details, nil, [])
end
assert_match %r{Missing partial parent/_foo with .*\n\nSearched in:\n \* "/Path/to/views"\n}, e.message
end
Expand Down

0 comments on commit e70b0a4

Please sign in to comment.