From 26dd9b26ab7317f94fd285245879e888344143b2 Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sat, 12 Nov 2016 12:33:37 +0100 Subject: [PATCH] significant speedup of AC::Parameters#permit The current implementation of AC::Parameters#permit builds permitted hashes and then calls permit! on them. This filtering is recursive, so we call permit! on terminal branches, but then ascendants call permit! on themselves when the recursion goes up the stack, which recurses all the way down again because permit! is recursive itself. Repeat this for every parent node and you get some scary O-something going on that I don't even want to compute. Instead, since the whole point of the permit recursion is to build permitted hashes along the way and at that point you know you've just come up with a valid filtered version, you can already switch the toggle on the spot. I have seen 2x speedups in casual benchmarks with small structures. As the previous description shows, the difference in performance is going to be a function of the nesting. Note that that the involved methods are private and used only by permit. --- actionpack/lib/action_controller/metal/strong_parameters.rb | 4 +++- .../test/controller/parameters/parameters_permit_test.rb | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 4d9ed976d6..1977632c4e 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -398,7 +398,8 @@ module ActionController unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters - params.permit! + params.permitted = true + params end # Returns a parameter for the given +key+. If not found, @@ -816,6 +817,7 @@ module ActionController # Filter this one out. end end + sanitized.permitted = true end end diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index 16637d330b..60bfb66f2f 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -187,6 +187,11 @@ class ParametersPermitTest < ActiveSupport::TestCase permitted = params.permit(:username, preferences: {}, hacked: {}) + assert permitted.permitted? + assert permitted[:preferences].permitted? + assert permitted[:preferences][:font].permitted? + assert permitted[:preferences][:dubious].all?(&:permitted?) + assert_equal "fxn", permitted[:username] assert_equal "Marazul", permitted[:preferences][:scheme] assert_equal "Source Code Pro", permitted[:preferences][:font][:name]