From f84b0ba7528fcbee822756b53ef6c226797688e6 Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Mon, 25 Apr 2022 15:44:09 +0300 Subject: [PATCH] Performance: improve .trim performance for large strings contains lots of whitespaces The old implementation took O(N^2) time to trim the string when multiple adjacent spaces were present. For instance, consider the string "A B" (10 spaces between A and B). Then old regexp /[\s]+$/ would take 10 steps until it realizes the regexp does not match at position 1. Then it would try to match the regexp at position 2, and it would take 9 steps. Then 8 steps for position 3, ... so it would take 10*10/2 steps until it figures out the regexp does not match. See https://github.com/jquery/jquery/pull/5068 The new approach is to require "non-whitespace" char before the whitespace run, so it spends just one step for each space in the string. --- src/jquery/core.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/jquery/core.js b/src/jquery/core.js index e67b5782..465cf6c1 100644 --- a/src/jquery/core.js +++ b/src/jquery/core.js @@ -15,9 +15,9 @@ var findProp, rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/, rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g, - // Support: Android <=4.0 only - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + // Require that the "whitespace run" starts from a non-whitespace + // to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position. + rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g; migratePatchFunc( jQuery.fn, "init", function( arg1 ) { var args = Array.prototype.slice.call( arguments ); @@ -109,7 +109,7 @@ if ( jQueryVersionSince( "3.1.1" ) ) { migratePatchAndWarnFunc( jQuery, "trim", function( text ) { return text == null ? "" : - ( text + "" ).replace( rtrim, "" ); + ( text + "" ).replace( rtrim, "$1" ); }, "trim", "jQuery.trim is deprecated; use String.prototype.trim" ); }