Skip to content

Commit

Permalink
querystring: improve performance
Browse files Browse the repository at this point in the history
PR-URL: #29306
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
  • Loading branch information
mscdex authored and BridgeAR committed Sep 3, 2019
1 parent e3cfbba commit 1223795
Showing 1 changed file with 31 additions and 37 deletions.
68 changes: 31 additions & 37 deletions lib/querystring.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,22 @@ function stringify(obj, sep, eq, options) {
for (var i = 0; i < len; ++i) {
var k = keys[i];
var v = obj[k];
var ks = encode(stringifyPrimitive(k)) + eq;
var ks = encode(stringifyPrimitive(k));
ks += eq;

if (Array.isArray(v)) {
var vlen = v.length;
if (vlen === 0) continue;
var vlast = vlen - 1;
for (var j = 0; j < vlen; ++j) {
fields += ks + encode(stringifyPrimitive(v[j]));
fields += ks;
fields += encode(stringifyPrimitive(v[j]));
if (j < vlast)
fields += sep;
}
} else {
fields += ks + encode(stringifyPrimitive(v));
fields += ks;
fields += encode(stringifyPrimitive(v));
}

if (i < flast)
Expand All @@ -200,14 +203,34 @@ function stringify(obj, sep, eq, options) {
function charCodes(str) {
if (str.length === 0) return [];
if (str.length === 1) return [str.charCodeAt(0)];
const ret = [];
const ret = new Array(str.length);
for (var i = 0; i < str.length; ++i)
ret[ret.length] = str.charCodeAt(i);
ret[i] = str.charCodeAt(i);
return ret;
}
const defSepCodes = [38]; // &
const defEqCodes = [61]; // =

function addKeyVal(obj, key, value, keyEncoded, valEncoded, decode) {
if (key.length > 0 && keyEncoded)
key = decodeStr(key, decode);
if (value.length > 0 && valEncoded)
value = decodeStr(value, decode);

if (obj[key] === undefined) {
obj[key] = value;
} else {
const curValue = obj[key];
// A simple Array-specific property check is enough here to
// distinguish from a string value and is faster and still safe
// since we are generating all of the values being assigned.
if (curValue.pop)
curValue[curValue.length] = value;
else
obj[key] = [curValue, value];
}
}

// Parse a key/val string.
function parse(qs, sep, eq, options) {
const obj = Object.create(null);
Expand Down Expand Up @@ -272,23 +295,8 @@ function parse(qs, sep, eq, options) {
value += qs.slice(lastPos, end);
}

if (key.length > 0 && keyEncoded)
key = decodeStr(key, decode);
if (value.length > 0 && valEncoded)
value = decodeStr(value, decode);
addKeyVal(obj, key, value, keyEncoded, valEncoded, decode);

if (obj[key] === undefined) {
obj[key] = value;
} else {
const curValue = obj[key];
// A simple Array-specific property check is enough here to
// distinguish from a string value and is faster and still safe
// since we are generating all of the values being assigned.
if (curValue.pop)
curValue[curValue.length] = value;
else
obj[key] = [curValue, value];
}
if (--pairs === 0)
return obj;
keyEncoded = valEncoded = customDecode;
Expand Down Expand Up @@ -370,22 +378,8 @@ function parse(qs, sep, eq, options) {
// We ended on an empty substring
return obj;
}
if (key.length > 0 && keyEncoded)
key = decodeStr(key, decode);
if (value.length > 0 && valEncoded)
value = decodeStr(value, decode);
if (obj[key] === undefined) {
obj[key] = value;
} else {
const curValue = obj[key];
// A simple Array-specific property check is enough here to
// distinguish from a string value and is faster and still safe since
// we are generating all of the values being assigned.
if (curValue.pop)
curValue[curValue.length] = value;
else
obj[key] = [curValue, value];
}

addKeyVal(obj, key, value, keyEncoded, valEncoded, decode);

return obj;
}
Expand Down

0 comments on commit 1223795

Please sign in to comment.