Skip to content

Commit a74cf37

Browse files
committed
perf: improve stringify performance
1 parent 438c216 commit a74cf37

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ console.log(qs.stringify({ foo: ['bar', 'baz'] }))
7070
╔════════════════════════════╤═════════╤═══════════════════╤═══════════╗
7171
║ Slower tests │ Samples │ Result │ Tolerance ║
7272
╟────────────────────────────┼─────────┼───────────────────┼───────────╢
73-
║ query-string │ 10000 │ 290850.12 op/sec │ ± 1.52 % ║
74-
║ qs │ 10000 │ 324324.45 op/sec │ ± 2.05 % ║
75-
║ http-querystring-stringify │ 10000 │ 481327.85 op/sec │ ± 1.77 % ║
76-
║ URLSearchParams │ 10000 │ 538867.84 op/sec │ ± 3.93 % ║
77-
║ querystringify │ 10000 │ 774992.18 op/sec │ ± 2.51 % ║
78-
║ node:querystring │ 10000 │ 1827458.66 op/sec │ ± 5.41 % ║
73+
║ query-string │ 10000 │ 284130.63 op/sec │ ± 1.62 % ║
74+
║ qs │ 10000 │ 334799.48 op/sec │ ± 1.93 % ║
75+
║ http-querystring-stringify │ 10000 │ 482642.49 op/sec │ ± 1.72 % ║
76+
║ URLSearchParams │ 10000 │ 587274.65 op/sec │ ± 1.88 % ║
77+
║ querystringify │ 10000 │ 753960.35 op/sec │ ± 2.20 % ║
78+
║ node:querystring │ 10000 │ 1796993.95 op/sec │ ± 5.34 % ║
7979
╟────────────────────────────┼─────────┼───────────────────┼───────────╢
8080
║ Fastest test │ Samples │ Result │ Tolerance ║
8181
╟────────────────────────────┼─────────┼───────────────────┼───────────╢
82-
║ fast-querystring │ 10000 │ 1881474.27 op/sec │ ± 4.78 % ║
82+
║ fast-querystring │ 10000 │ 2051022.89 op/sec │ ± 4.52 % ║
8383
╚════════════════════════════╧═════════╧═══════════════════╧═══════════╝
8484
```

lib/stringify.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,33 @@ function stringify(input) {
3434

3535
const keys = Object.getOwnPropertyNames(input);
3636
const keyLength = keys.length;
37+
const separator = "&";
38+
let valueLength = 0;
3739

3840
for (let i = 0; i < keyLength; i++) {
3941
const key = keys[i];
4042
const value = input[key];
4143
const encodedKey = encodeString(key) + "=";
4244

4345
if (i) {
44-
result += "&";
46+
result += separator;
4547
}
4648

4749
if (Array.isArray(value)) {
48-
const valueLength = value.length;
50+
valueLength = value.length;
4951
for (let j = 0; j < valueLength; j++) {
5052
if (j) {
51-
result += "&";
53+
result += separator;
5254
}
5355

54-
result += encodedKey + getAsPrimitive(value[j]);
56+
// Optimization: Dividing into multiple lines improves the performance.
57+
// Since v8 does not need to care about the '+' character if it was one-liner.
58+
result += encodedKey;
59+
result += getAsPrimitive(value[j]);
5560
}
5661
} else {
57-
result += encodedKey + getAsPrimitive(value);
62+
result += encodedKey;
63+
result += getAsPrimitive(value);
5864
}
5965
}
6066

0 commit comments

Comments
 (0)