mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
querystring: improve stringify() performance
PR-URL: https://github.com/nodejs/node/pull/33669 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
3 files changed
+47
-14
No files matched your search
@@ -3,7 +3,7 @@ const common = require('../common.js');
|
|||||||
const querystring = require('querystring');
|
const querystring = require('querystring');
|
||||||
|
|
||||||
const bench = common.createBenchmark(main, {
|
const bench = common.createBenchmark(main, {
|
||||||
type: ['noencode', 'encodemany', 'encodelast', 'array'],
|
type: ['noencode', 'encodemany', 'encodelast', 'array', 'multiprimitives'],
|
||||||
n: [1e6],
|
n: [1e6],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -28,7 +28,12 @@ function main({ type, n }) {
|
|||||||
foo: [],
|
foo: [],
|
||||||
baz: ['bar'],
|
baz: ['bar'],
|
||||||
xyzzy: ['bar', 'quux', 'thud']
|
xyzzy: ['bar', 'quux', 'thud']
|
||||||
}
|
},
|
||||||
|
multiprimitives: {
|
||||||
|
foo: false,
|
||||||
|
bar: -13.37,
|
||||||
|
baz: '',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const input = inputs[type];
|
const input = inputs[type];
|
||||||
|
|
||||||
|
|||||||
@@ -36,19 +36,25 @@ function encodeStr(str, noEscapeTable, hexTable) {
|
|||||||
|
|
||||||
let out = '';
|
let out = '';
|
||||||
let lastPos = 0;
|
let lastPos = 0;
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
for (let i = 0; i < len; i++) {
|
outer:
|
||||||
|
for (; i < len; i++) {
|
||||||
let c = str.charCodeAt(i);
|
let c = str.charCodeAt(i);
|
||||||
|
|
||||||
// ASCII
|
// ASCII
|
||||||
if (c < 0x80) {
|
while (c < 0x80) {
|
||||||
if (noEscapeTable[c] === 1)
|
if (noEscapeTable[c] !== 1) {
|
||||||
continue;
|
if (lastPos < i)
|
||||||
if (lastPos < i)
|
out += str.slice(lastPos, i);
|
||||||
out += str.slice(lastPos, i);
|
lastPos = i + 1;
|
||||||
lastPos = i + 1;
|
out += hexTable[c];
|
||||||
out += hexTable[c];
|
}
|
||||||
continue;
|
|
||||||
|
if (++i === len)
|
||||||
|
break outer;
|
||||||
|
|
||||||
|
c = str.charCodeAt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastPos < i)
|
if (lastPos < i)
|
||||||
|
|||||||
+25
-3
@@ -26,6 +26,7 @@
|
|||||||
const {
|
const {
|
||||||
Array,
|
Array,
|
||||||
ArrayIsArray,
|
ArrayIsArray,
|
||||||
|
MathAbs,
|
||||||
ObjectCreate,
|
ObjectCreate,
|
||||||
ObjectKeys,
|
ObjectKeys,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
@@ -162,6 +163,25 @@ function stringifyPrimitive(v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function encodeStringified(v, encode) {
|
||||||
|
if (typeof v === 'string')
|
||||||
|
return (v.length ? encode(v) : '');
|
||||||
|
if (typeof v === 'number' && isFinite(v)) {
|
||||||
|
// Values >= 1e21 automatically switch to scientific notation which requires
|
||||||
|
// escaping due to the inclusion of a '+' in the output
|
||||||
|
return (MathAbs(v) < 1e21 ? '' + v : encode('' + v));
|
||||||
|
}
|
||||||
|
if (typeof v === 'boolean')
|
||||||
|
return v ? 'true' : 'false';
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function encodeStringifiedCustom(v, encode) {
|
||||||
|
return encode(stringifyPrimitive(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function stringify(obj, sep, eq, options) {
|
function stringify(obj, sep, eq, options) {
|
||||||
sep = sep || '&';
|
sep = sep || '&';
|
||||||
eq = eq || '=';
|
eq = eq || '=';
|
||||||
@@ -170,6 +190,8 @@ function stringify(obj, sep, eq, options) {
|
|||||||
if (options && typeof options.encodeURIComponent === 'function') {
|
if (options && typeof options.encodeURIComponent === 'function') {
|
||||||
encode = options.encodeURIComponent;
|
encode = options.encodeURIComponent;
|
||||||
}
|
}
|
||||||
|
const convert =
|
||||||
|
(encode === qsEscape ? encodeStringified : encodeStringifiedCustom);
|
||||||
|
|
||||||
if (obj !== null && typeof obj === 'object') {
|
if (obj !== null && typeof obj === 'object') {
|
||||||
const keys = ObjectKeys(obj);
|
const keys = ObjectKeys(obj);
|
||||||
@@ -179,7 +201,7 @@ function stringify(obj, sep, eq, options) {
|
|||||||
for (let i = 0; i < len; ++i) {
|
for (let i = 0; i < len; ++i) {
|
||||||
const k = keys[i];
|
const k = keys[i];
|
||||||
const v = obj[k];
|
const v = obj[k];
|
||||||
let ks = encode(stringifyPrimitive(k));
|
let ks = convert(k, encode);
|
||||||
ks += eq;
|
ks += eq;
|
||||||
|
|
||||||
if (ArrayIsArray(v)) {
|
if (ArrayIsArray(v)) {
|
||||||
@@ -188,13 +210,13 @@ function stringify(obj, sep, eq, options) {
|
|||||||
const vlast = vlen - 1;
|
const vlast = vlen - 1;
|
||||||
for (let j = 0; j < vlen; ++j) {
|
for (let j = 0; j < vlen; ++j) {
|
||||||
fields += ks;
|
fields += ks;
|
||||||
fields += encode(stringifyPrimitive(v[j]));
|
fields += convert(v[j], encode);
|
||||||
if (j < vlast)
|
if (j < vlast)
|
||||||
fields += sep;
|
fields += sep;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fields += ks;
|
fields += ks;
|
||||||
fields += encode(stringifyPrimitive(v));
|
fields += convert(v, encode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < flast)
|
if (i < flast)
|
||||||
|
|||||||
Reference in new issue
Block a user