var v8 = require('v8');
var bench = common.createBenchmark(main, {
- type: ['noencode', 'encodemany', 'encodelast'],
+ type: ['noencode', 'encodemany', 'encodelast', 'multivalue'],
n: [1e6],
});
var inputs = {
noencode: 'foo=bar&baz=quux&xyzzy=thud',
encodemany: '%66%6F%6F=bar&%62%61%7A=quux&xyzzy=%74h%75d',
- encodelast: 'foo=bar&baz=quux&xyzzy=thu%64'
+ encodelast: 'foo=bar&baz=quux&xyzzy=thu%64',
+ multivalue: 'foo=bar&foo=baz&foo=quux&quuy=quuz'
};
var input = inputs[type];
return obj;
}
- var regexp = /\+/g;
qs = qs.split(sep);
var maxKeys = 1000;
var keys = [];
for (var i = 0; i < len; ++i) {
- const x = qs[i].replace(regexp, '%20');
+ // replacePlus() is used instead of a regexp because it is ~15-30% faster
+ // with v8 4.7
+ const x = replacePlus(qs[i]);
const idx = x.indexOf(eq);
var k, v;
v = '';
}
+ // Use a key array lookup instead of using hasOwnProperty(), which is slower
if (keys.indexOf(k) === -1) {
obj[k] = v;
keys.push(k);
- } else if (Array.isArray(obj[k])) {
+ } else if (obj[k] instanceof Array) {
+ // `instanceof Array` is used instead of Array.isArray() because it is
+ // ~15-20% faster with v8 4.7 and is safe to use because we are using it
+ // with values being created within this function
obj[k].push(v);
} else {
obj[k] = [obj[k], v];
};
+function replacePlus(str) {
+ var ret = '';
+ var start = 0;
+ var i = -1;
+ while ((i = str.indexOf('+', i + 1)) !== -1) {
+ ret += str.slice(start, i);
+ ret += '%20';
+ start = i + 1;
+ }
+ if (start === 0)
+ return str;
+ if (start < str.length)
+ ret += str.slice(start);
+ return ret;
+}
+
+
+// v8 does not optimize functions with try-catch blocks, so we isolate them here
+// to minimize the damage
function decodeStr(s, decoder) {
try {
return decoder(s);