Skip to content

Commit

Permalink
perf: improve stringify performance
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Sep 6, 2022
1 parent 438c216 commit a74cf37
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ console.log(qs.stringify({ foo: ['bar', 'baz'] }))
╔════════════════════════════╤═════════╤═══════════════════╤═══════════╗
║ Slower tests │ Samples │ Result │ Tolerance ║
╟────────────────────────────┼─────────┼───────────────────┼───────────╢
║ query-string │ 10000 │ 290850.12 op/sec │ ± 1.52 % ║
║ qs │ 10000 │ 324324.45 op/sec │ ± 2.05 % ║
║ http-querystring-stringify │ 10000 │ 481327.85 op/sec │ ± 1.77 % ║
║ URLSearchParams │ 10000 │ 538867.84 op/sec │ ± 3.93 % ║
║ querystringify │ 10000 │ 774992.18 op/sec │ ± 2.51 % ║
║ node:querystring │ 10000 │ 1827458.66 op/sec │ ± 5.41 % ║
║ query-string │ 10000 │ 284130.63 op/sec │ ± 1.62 % ║
║ qs │ 10000 │ 334799.48 op/sec │ ± 1.93 % ║
║ http-querystring-stringify │ 10000 │ 482642.49 op/sec │ ± 1.72 % ║
║ URLSearchParams │ 10000 │ 587274.65 op/sec │ ± 1.88 % ║
║ querystringify │ 10000 │ 753960.35 op/sec │ ± 2.20 % ║
║ node:querystring │ 10000 │ 1796993.95 op/sec │ ± 5.34 % ║
╟────────────────────────────┼─────────┼───────────────────┼───────────╢
║ Fastest test │ Samples │ Result │ Tolerance ║
╟────────────────────────────┼─────────┼───────────────────┼───────────╢
║ fast-querystring │ 10000 │ 1881474.27 op/sec │ ± 4.78 % ║
║ fast-querystring │ 10000 │ 2051022.89 op/sec │ ± 4.52 % ║
╚════════════════════════════╧═════════╧═══════════════════╧═══════════╝
```
16 changes: 11 additions & 5 deletions lib/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,33 @@ function stringify(input) {

const keys = Object.getOwnPropertyNames(input);
const keyLength = keys.length;
const separator = "&";
let valueLength = 0;

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

if (i) {
result += "&";
result += separator;
}

if (Array.isArray(value)) {
const valueLength = value.length;
valueLength = value.length;
for (let j = 0; j < valueLength; j++) {
if (j) {
result += "&";
result += separator;
}

result += encodedKey + getAsPrimitive(value[j]);
// Optimization: Dividing into multiple lines improves the performance.
// Since v8 does not need to care about the '+' character if it was one-liner.
result += encodedKey;
result += getAsPrimitive(value[j]);
}
} else {
result += encodedKey + getAsPrimitive(value);
result += encodedKey;
result += getAsPrimitive(value);
}
}

Expand Down

0 comments on commit a74cf37

Please sign in to comment.