Skip to content

Commit 8b65d89

Browse files
committed
perf: improve parsing performance by pruning
1 parent ce732de commit 8b65d89

File tree

2 files changed

+35
-17
lines changed

2 files changed

+35
-17
lines changed

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ console.log(qs.stringify({ foo: ['bar', 'baz'] }))
4848
╔═════════════════════════════════════════╤═════════╤═══════════════════╤═══════════╗
4949
║ Slower tests │ Samples │ Result │ Tolerance ║
5050
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
51-
║ qs │ 9000 320475.01 op/sec │ ± 1.00 % ║
52-
║ query-string │ 10000 │ 329524.10 op/sec │ ± 1.33 % ║
53-
║ querystringify │ 1000 447654.63 op/sec │ ± 0.64 % ║
54-
║ @aws-sdk/querystring-parser │ 1000 │ 467889.89 op/sec │ ± 0.75 % ║
55-
║ URLSearchParams-with-Object.fromEntries │ 10000 │ 836523.77 op/sec │ ± 3.43 % ║
56-
║ URLSearchParams-with-construct │ 10000 │ 1239361.94 op/sec │ ± 2.88 % ║
57-
║ node:querystring │ 10000 │ 1399756.44 op/sec │ ± 4.07 % ║
51+
║ qs │ 10000 310498.16 op/sec │ ± 1.40 % ║
52+
║ query-string │ 10000 │ 335094.41 op/sec │ ± 1.06 % ║
53+
║ querystringify │ 10000 444913.68 op/sec │ ± 1.32 % ║
54+
║ @aws-sdk/querystring-parser │ 1000 │ 462867.39 op/sec │ ± 0.75 % ║
55+
║ URLSearchParams-with-Object.fromEntries │ 10000 │ 830585.13 op/sec │ ± 3.19 % ║
56+
║ URLSearchParams-with-construct │ 10000 │ 1216221.57 op/sec │ ± 3.46 % ║
57+
║ node:querystring │ 3500 │ 1407749.94 op/sec │ ± 0.91 % ║
5858
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
5959
║ Fastest test │ Samples │ Result │ Tolerance ║
6060
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
61-
║ fast-querystring │ 5500 │ 1496630.81 op/sec │ ± 0.98 % ║
61+
║ fast-querystring │ 10000 │ 1575870.52 op/sec │ ± 2.80 % ║
6262
╚═════════════════════════════════════════╧═════════╧═══════════════════╧═══════════╝
6363
```
6464

lib/parse.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ function parse(input) {
1818
let value = "";
1919
let startingIndex = -1;
2020
let equalityIndex = -1;
21-
let shouldDecode = false;
22-
let hasPlus = false;
21+
let shouldDecodeKey = false;
22+
let shouldDecodeValue = false;
23+
let keyHasPlus = false;
24+
let valueHasPlus = false;
2325

2426
// Have a boundary of input.length + 1 to access last pair inside the loop.
2527
for (let i = 0; i < inputLength + 1; i++) {
@@ -41,14 +43,20 @@ function parse(input) {
4143
// Add key/value pair only if the range size is greater than 1; a.k.a. contains at least "="
4244
if (i - startingIndex > 1) {
4345
// Optimization: Replace '+' with space
44-
if (hasPlus) {
46+
if (keyHasPlus) {
4547
key = key.replaceAll("+", " ");
48+
}
49+
50+
if (valueHasPlus) {
4651
value = value.replaceAll("+", " ");
4752
}
4853

4954
// Optimization: Do not decode if it's not necessary.
50-
if (shouldDecode) {
55+
if (shouldDecodeKey) {
5156
key = fastDecode(key) || key;
57+
}
58+
59+
if (shouldDecodeValue) {
5260
value = fastDecode(value) || value;
5361
}
5462

@@ -70,25 +78,35 @@ function parse(input) {
7078
value = "";
7179
startingIndex = i;
7280
equalityIndex = i;
73-
shouldDecode = false;
74-
hasPlus = false;
81+
shouldDecodeKey = false;
82+
shouldDecodeValue = false;
83+
keyHasPlus = false;
84+
valueHasPlus = false;
7585
}
7686
// Check '='
7787
else if (c === 61) {
7888
// If '=' character occurs again, we should decode the input.
7989
if (equalityIndex > startingIndex) {
80-
shouldDecode = true;
90+
shouldDecodeValue = true;
8191
} else {
8292
equalityIndex = i;
8393
}
8494
}
8595
// Check '+', and replace it with empty space.
8696
else if (c === 43) {
87-
hasPlus = true;
97+
if (equalityIndex <= startingIndex) {
98+
keyHasPlus = true;
99+
} else {
100+
valueHasPlus = true;
101+
}
88102
}
89103
// Check '%' character for encoding
90104
else if (c === 37) {
91-
shouldDecode = true;
105+
if (equalityIndex <= startingIndex) {
106+
shouldDecodeKey = true;
107+
} else {
108+
shouldDecodeValue = true;
109+
}
92110
}
93111
}
94112

0 commit comments

Comments
 (0)