Skip to content

Commit d4f66af

Browse files
committed
url: improve URLSearchParams.toString() performance
Refs: nodejs/performance#56
1 parent 42be7f6 commit d4f66af

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
4+
const bench = common.createBenchmark(main, {
5+
n: [1e6],
6+
});
7+
8+
const value = {
9+
str: 'foo',
10+
array: ['bar', 'baz', 'bal'],
11+
bool: true,
12+
bigInt: BigInt(100),
13+
num: 256,
14+
};
15+
16+
function main({ n }) {
17+
bench.start();
18+
for (let i = 0; i < n; i++)
19+
new URLSearchParams(value).toString();
20+
bench.end(n);
21+
}

lib/internal/url.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const {
44
Array,
5+
ArrayIsArray,
56
ArrayPrototypeJoin,
67
ArrayPrototypeMap,
78
ArrayPrototypePush,
@@ -211,7 +212,17 @@ class URLSearchParams {
211212
const desc = ReflectGetOwnPropertyDescriptor(init, key);
212213
if (desc !== undefined && desc.enumerable) {
213214
const typedKey = toUSVString(key);
214-
const typedValue = toUSVString(init[key]);
215+
let typedValue = '';
216+
if (ArrayIsArray(init[key])) {
217+
const len = init[key].length;
218+
for (let j = 0; j < len; j++) {
219+
typedValue += toUSVString(init[key][j]);
220+
if (j < len - 1)
221+
typedValue += ',';
222+
}
223+
} else {
224+
typedValue = toUSVString(init[key]);
225+
}
215226

216227
// Two different key may result same after `toUSVString()`, we only
217228
// leave the later one. Refers to WPT.
@@ -1017,12 +1028,17 @@ function serializeParams(array) {
10171028

10181029
const firstEncodedParam = encodeStr(array[0], noEscape, paramHexTable);
10191030
const firstEncodedValue = encodeStr(array[1], noEscape, paramHexTable);
1020-
let output = `${firstEncodedParam}=${firstEncodedValue}`;
1031+
let output = firstEncodedParam;
1032+
output += '=';
1033+
output += firstEncodedValue;
10211034

10221035
for (let i = 2; i < len; i += 2) {
10231036
const encodedParam = encodeStr(array[i], noEscape, paramHexTable);
10241037
const encodedValue = encodeStr(array[i + 1], noEscape, paramHexTable);
1025-
output += `&${encodedParam}=${encodedValue}`;
1038+
output += '&';
1039+
output += encodedParam;
1040+
output += '=';
1041+
output += encodedValue;
10261042
}
10271043

10281044
return output;

0 commit comments

Comments
 (0)