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
Optimize mime types validation in ActionView::LookupContext #48163
Conversation
The `Type` class was introduced in rails#23085 for the sole purpose of breaking the dependency of Action View on Action Dispatch. Unless you are somehow running Action View standalone, this is actually never used. So instead of delegating, we can use constant swapping, this saves us a useless layer. Ultimately we could consider moving `Mime::Types` into Active Support but it requires some more thoughts.
Fix: rails#48156 The assumption here is that in the overwhelming majority of cases, all formats are valid. So we first check if any of the formats is invalid before duping the details hash and filtering them. Additonally, by exposing a (non-public) `valid_symbols?` method, we can check symbols are valid without resporting to `Array#%` which would needlessly duplicate the `formats` array.
Assuming the overwhelming majority of the time `details[:formats]` is all valid, we can first check the cache with the unmofidied `details` and then only if we miss we filter the valid formats.
Benchmark: begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
rails = ENV.fetch("RAILS", "edge")
gemfile(true) do
source "https://rubygems.org"
if rails == "edge"
gem "actionpack", github: "rails/rails"
gem "actionview", github: "rails/rails"
elsif rails == "local"
gem "actionpack", path: "/Users/byroot/src/github.com/Shopify/rails"
gem "actionview", path: "/Users/byroot/src/github.com/Shopify/rails"
end
gem "benchmark-ips"
end
require "action_controller"
require "action_view"
details = {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby]}
Benchmark.ips do |x|
x.report("details_cache_key") { ActionView::LookupContext::DetailsKey.details_cache_key(details) }
end
This branch:
|
This branch without the last commit:
So I think the other optimizations are worth it to optimize on miss. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good to me
Yeah, essentially it's only purpose is to avoid a dependency on mime-types from ActionView, which I think could be worth revisiting, but the constant reassignment should at least make it a non-issue for performance. |
I've profiled a bit, but most of the time is now spent computing the hash code for |
Fix: #48156
The assumption here is that in the overwhelming majority of cases, all formats are valid.
So we first check if any of the formats is invalid before duping the details hash and filtering them.
Additionally, by exposing a (non-public)
valid_symbols?
method, we can check symbols are valid without resporting toArray#%
which would needlessly duplicate theformats
array.This optimization is based on a prior refactor of ActionView::Template::Types to avoid delegation.
The
Type
class was introduced in #23085 for the sole purpose of breaking the dependency of Action View on Action Dispatch.Unless you are somehow running Action View standalone, this is actually never used.
So instead of delegating, we can use constant swapping, this saves us a useless layer.
Ultimately we could consider moving
Mime::Types
into Active Support but it requires some more thoughts.cc @headius @ghiculescu
Also cc @jhawthorn as I see you've optimized the
Template::Types
delegation in the past.I still need to benchmark to see how much we gain here, and if another approach may be faster, but I'd like to first check CI is green.