Commit 6a6e09e8344 for nodejs

commit 6a6e09e834433d7c8f75ba45ad79fea9e76473c6
Author: Yagiz Nizipli <yagiz@nizipli.com>
Date:   Sat Sep 26 16:34:53 2026 -0400

    querystring: speed up default parse and unescape

    Skip the %XX walk in unescapeBuffer when the input has no '%'.
    Add a dedicated '&'/'=' scanner for the default parse path so
    it does not build separator code arrays or run the multi-char
    state machine.

    Official benchmark/querystring/querystring-parse.js:
    encodemany is about 38% faster, manyblankpairs about 17%,
    encodelast about 10%, noencode about 8%.
    Official querystring-unescapebuffer.js with no escapes is
    about 36% faster.

    Assisted-by: a closed-source coding agent
    Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
    Co-authored-by: Yagiz Nizipli <anonrig@users.noreply.github.com>
    PR-URL: https://github.com/nodejs/node/pull/66175
    Reviewed-By: James M Snell <jasnell@gmail.com>
    Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>

diff --git a/lib/querystring.js b/lib/querystring.js
index 30e159d647b..6aca65dee5b 100644
--- a/lib/querystring.js
+++ b/lib/querystring.js
@@ -32,6 +32,7 @@ const {
   ObjectKeys,
   String,
   StringPrototypeCharCodeAt,
+  StringPrototypeIndexOf,
   StringPrototypeSlice,
   decodeURIComponent,
 } = primordials;
@@ -82,6 +83,11 @@ const unhexTable = new Int8Array([
  * @returns {string}
  */
 function unescapeBuffer(s, decodeSpaces) {
+  // No encoded bytes: latin1-copy the string without walking %XX.
+  if (StringPrototypeIndexOf(s, '%') === -1) {
+    if (!decodeSpaces || StringPrototypeIndexOf(s, '+') === -1)
+      return Buffer.from(s, 'latin1');
+  }
   const out = Buffer.allocUnsafe(s.length);
   let index = 0;
   let outIndex = 0;
@@ -303,6 +309,120 @@ function addKeyVal(obj, key, value, keyEncoded, valEncoded, decode) {
   }
 }

+/**
+ * Default querystring parser: separator '&', equals '=', native unescape.
+ * Single-character separators avoid the sep/eq index state machine.
+ * @param {string} qs
+ * @param {Record<string, string | string[]>} obj
+ * @returns {Record<string, string | string[]>}
+ */
+function parseAmpEq(qs, obj) {
+  let pairs = 1000;
+  let lastPos = 0;
+  let eqPos = -1;
+  let key = '';
+  let value = '';
+  let keyEncoded = false;
+  let valEncoded = false;
+  let encodeCheck = 0;
+  const plusChar = ' ';
+  const len = qs.length;
+
+  for (let i = 0; i < len; ++i) {
+    const code = StringPrototypeCharCodeAt(qs, i);
+
+    if (code === 38) { // '&'
+      const end = i;
+      if (eqPos === -1) {
+        if (lastPos < end)
+          key += StringPrototypeSlice(qs, lastPos, end);
+        else if (key.length === 0) {
+          if (--pairs === 0)
+            return obj;
+          lastPos = i + 1;
+          encodeCheck = 0;
+          continue;
+        }
+      } else if (lastPos < end) {
+        value += StringPrototypeSlice(qs, lastPos, end);
+      }
+
+      addKeyVal(obj, key, value, keyEncoded, valEncoded, qsUnescape);
+
+      if (--pairs === 0)
+        return obj;
+      keyEncoded = false;
+      valEncoded = false;
+      key = '';
+      value = '';
+      encodeCheck = 0;
+      lastPos = i + 1;
+      eqPos = -1;
+      continue;
+    }
+
+    if (eqPos === -1) {
+      if (code === 61) { // '='
+        if (lastPos < i)
+          key += StringPrototypeSlice(qs, lastPos, i);
+        encodeCheck = 0;
+        lastPos = i + 1;
+        eqPos = i;
+        continue;
+      }
+      if (!keyEncoded) {
+        if (code === 37) {
+          encodeCheck = 1;
+        } else if (encodeCheck > 0) {
+          if (isHexTable[code] === 1) {
+            if (++encodeCheck === 3)
+              keyEncoded = true;
+          } else {
+            encodeCheck = 0;
+          }
+        }
+      }
+      if (code === 43) {
+        if (lastPos < i)
+          key += StringPrototypeSlice(qs, lastPos, i);
+        key += plusChar;
+        lastPos = i + 1;
+      }
+      continue;
+    }
+
+    if (code === 43) {
+      if (lastPos < i)
+        value += StringPrototypeSlice(qs, lastPos, i);
+      value += plusChar;
+      lastPos = i + 1;
+    } else if (!valEncoded) {
+      if (code === 37) {
+        encodeCheck = 1;
+      } else if (encodeCheck > 0) {
+        if (isHexTable[code] === 1) {
+          if (++encodeCheck === 3)
+            valEncoded = true;
+        } else {
+          encodeCheck = 0;
+        }
+      }
+    }
+  }
+
+  if (lastPos < len) {
+    if (eqPos === -1)
+      key += StringPrototypeSlice(qs, lastPos);
+    else
+      value += StringPrototypeSlice(qs, lastPos);
+  } else if (eqPos === -1 && key.length === 0) {
+    return obj;
+  }
+
+  addKeyVal(obj, key, value, keyEncoded, valEncoded, qsUnescape);
+  return obj;
+}
+
 /**
  * Parse a key/val string.
  * @param {string} qs
@@ -321,6 +441,16 @@ function parse(qs, sep, eq, options) {
     return obj;
   }

+  // Default '&' / '=' / unescape: single-char scanner, no sep/eq arrays.
+  if ((sep === undefined || sep === '&') &&
+      (eq === undefined || eq === '=') &&
+      QueryString.unescape === qsUnescape &&
+      (!options ||
+       (options.maxKeys === undefined &&
+        options.decodeURIComponent === undefined))) {
+    return parseAmpEq(qs, obj);
+  }
+
   const sepCodes = (!sep ? defSepCodes : charCodes(String(sep)));
   const eqCodes = (!eq ? defEqCodes : charCodes(String(eq)));
   const sepLen = sepCodes.length;