Merge pull request #42779 from jhawthorn/faster_template_lookups

Speed up template lookups by avoiding splats and ===
This commit is contained in:
John Hawthorn 2021-07-14 07:05:55 -07:00 committed by GitHub
commit e70b0a47a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 28 deletions

@ -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?
@ -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.
@ -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 = {}

@ -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)

@ -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