-
Jonathan Hefner authored
`ActiveSupport::ParameterFilter.precompile_filters` precompiles filters that otherwise would be passed directly to `ParameterFilter.new`. Depending on the quantity and types of filters, precompilation can improve filtering performance, especially in the case where the `ParameterFilter` instance cannot be retained, such as with per-request instances in `ActionDispatch::Http::FilterParameters`. **Benchmark script** ```ruby # frozen_string_literal: true require "benchmark/ips" require "benchmark/memory" require "active_support" require "active_support/parameter_filter" ootb = [:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn] mixed = [:passw, "secret", /token/, :crypt, "salt", /certificate/, "user.otp", /user\.ssn/, proc {}] precompiled_ootb = ActiveSupport::ParameterFilter.precompile_filters(ootb) precompiled_mixed = ActiveSupport::ParameterFilter.precompile_filters(mixed) params = { "user" => { "name" => :name, "email" => :email, "password" => :password, "ssn" => :ssn, "locations" => [ { "city" => :city, "country" => :country }, { "city" => :city, "country" => :country }, ], } } Benchmark.ips do |x| x.report("ootb") do ActiveSupport::ParameterFilter.new(ootb).filter(params) end x.report("precompiled ootb") do ActiveSupport::ParameterFilter.new(precompiled_ootb).filter(params) end x.compare! end Benchmark.ips do |x| x.report("mixed") do ActiveSupport::ParameterFilter.new(mixed).filter(params) end x.report("precompiled mixed") do ActiveSupport::ParameterFilter.new(precompiled_mixed).filter(params) end x.compare! end Benchmark.memory do |x| x.report("ootb") do ActiveSupport::ParameterFilter.new(ootb).filter(params) end x.report("precompiled ootb") do ActiveSupport::ParameterFilter.new(precompiled_ootb).filter(params) end end Benchmark.memory do |x| x.report("mixed") do ActiveSupport::ParameterFilter.new(mixed).filter(params) end x.report("precompiled mixed") do ActiveSupport::ParameterFilter.new(precompiled_mixed).filter(params) end end ``` **Results** ``` Warming up -------------------------------------- ootb 2.151k i/100ms precompiled ootb 4.251k i/100ms Calculating ------------------------------------- ootb 21.567k (± 1.1%) i/s - 109.701k in 5.086983s precompiled ootb 42.840k (± 0.8%) i/s - 216.801k in 5.061022s Comparison: precompiled ootb: 42840.4 i/s ootb: 21567.5 i/s - 1.99x (± 0.00) slower ``` ``` Warming up -------------------------------------- mixed 1.622k i/100ms precompiled mixed 2.455k i/100ms Calculating ------------------------------------- mixed 16.085k (± 1.3%) i/s - 81.100k in 5.042764s precompiled mixed 24.640k (± 1.0%) i/s - 125.205k in 5.081988s Comparison: precompiled mixed: 24639.6 i/s mixed: 16085.0 i/s - 1.53x (± 0.00) slower ``` ``` Calculating ------------------------------------- ootb 2.684k memsize ( 0.000 retained) 30.000 objects ( 0.000 retained) 10.000 strings ( 0.000 retained) precompiled ootb 1.104k memsize ( 0.000 retained) 9.000 objects ( 0.000 retained) 1.000 strings ( 0.000 retained) ``` ``` Calculating ------------------------------------- mixed 3.541k memsize ( 0.000 retained) 46.000 objects ( 0.000 retained) 20.000 strings ( 0.000 retained) precompiled mixed 1.856k memsize ( 0.000 retained) 29.000 objects ( 0.000 retained) 13.000 strings ( 0.000 retained) ``` This commit also adds `config.precompile_filter_parameters`, which enables precompilation of `config.filter_parameters`. It defaults to `true` for `config.load_defaults 7.1` and above.
Jonathan Hefner authored`ActiveSupport::ParameterFilter.precompile_filters` precompiles filters that otherwise would be passed directly to `ParameterFilter.new`. Depending on the quantity and types of filters, precompilation can improve filtering performance, especially in the case where the `ParameterFilter` instance cannot be retained, such as with per-request instances in `ActionDispatch::Http::FilterParameters`. **Benchmark script** ```ruby # frozen_string_literal: true require "benchmark/ips" require "benchmark/memory" require "active_support" require "active_support/parameter_filter" ootb = [:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn] mixed = [:passw, "secret", /token/, :crypt, "salt", /certificate/, "user.otp", /user\.ssn/, proc {}] precompiled_ootb = ActiveSupport::ParameterFilter.precompile_filters(ootb) precompiled_mixed = ActiveSupport::ParameterFilter.precompile_filters(mixed) params = { "user" => { "name" => :name, "email" => :email, "password" => :password, "ssn" => :ssn, "locations" => [ { "city" => :city, "country" => :country }, { "city" => :city, "country" => :country }, ], } } Benchmark.ips do |x| x.report("ootb") do ActiveSupport::ParameterFilter.new(ootb).filter(params) end x.report("precompiled ootb") do ActiveSupport::ParameterFilter.new(precompiled_ootb).filter(params) end x.compare! end Benchmark.ips do |x| x.report("mixed") do ActiveSupport::ParameterFilter.new(mixed).filter(params) end x.report("precompiled mixed") do ActiveSupport::ParameterFilter.new(precompiled_mixed).filter(params) end x.compare! end Benchmark.memory do |x| x.report("ootb") do ActiveSupport::ParameterFilter.new(ootb).filter(params) end x.report("precompiled ootb") do ActiveSupport::ParameterFilter.new(precompiled_ootb).filter(params) end end Benchmark.memory do |x| x.report("mixed") do ActiveSupport::ParameterFilter.new(mixed).filter(params) end x.report("precompiled mixed") do ActiveSupport::ParameterFilter.new(precompiled_mixed).filter(params) end end ``` **Results** ``` Warming up -------------------------------------- ootb 2.151k i/100ms precompiled ootb 4.251k i/100ms Calculating ------------------------------------- ootb 21.567k (± 1.1%) i/s - 109.701k in 5.086983s precompiled ootb 42.840k (± 0.8%) i/s - 216.801k in 5.061022s Comparison: precompiled ootb: 42840.4 i/s ootb: 21567.5 i/s - 1.99x (± 0.00) slower ``` ``` Warming up -------------------------------------- mixed 1.622k i/100ms precompiled mixed 2.455k i/100ms Calculating ------------------------------------- mixed 16.085k (± 1.3%) i/s - 81.100k in 5.042764s precompiled mixed 24.640k (± 1.0%) i/s - 125.205k in 5.081988s Comparison: precompiled mixed: 24639.6 i/s mixed: 16085.0 i/s - 1.53x (± 0.00) slower ``` ``` Calculating ------------------------------------- ootb 2.684k memsize ( 0.000 retained) 30.000 objects ( 0.000 retained) 10.000 strings ( 0.000 retained) precompiled ootb 1.104k memsize ( 0.000 retained) 9.000 objects ( 0.000 retained) 1.000 strings ( 0.000 retained) ``` ``` Calculating ------------------------------------- mixed 3.541k memsize ( 0.000 retained) 46.000 objects ( 0.000 retained) 20.000 strings ( 0.000 retained) precompiled mixed 1.856k memsize ( 0.000 retained) 29.000 objects ( 0.000 retained) 13.000 strings ( 0.000 retained) ``` This commit also adds `config.precompile_filter_parameters`, which enables precompilation of `config.filter_parameters`. It defaults to `true` for `config.load_defaults 7.1` and above.
Loading