Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fe5b710
build: add option to select VS version
greenjava Jan 12, 2016
8bf5b33
crypto: clear error stack in ECDH::Initialize
indutny Jan 14, 2016
0d0a5ed
debugger: remove variable redeclarations
Trott Jan 11, 2016
dcaf6fd
doc: clarify protocol default in http.request()
cjihrig Jan 15, 2016
43dfd03
doc: update branch-diff arguments in release doc
rvagg Jan 14, 2016
01bdafe
doc: fix named anchors in addons.markdown and http.markdown
MichaelTheriot Jan 15, 2016
a6c242f
doc: add path property to Write/ReadStream in fs.markdown
claudiorodriguez Dec 20, 2015
056b078
doc: clarify explanation of first stream section
vccortez Dec 10, 2015
a8330f7
events: make sure console functions exist
Dec 30, 2015
2879395
fs: add autoClose option to fs.createWriteStream
saquibkhan Nov 29, 2015
c171294
http: improves expect header handling
designfrontier Dec 31, 2015
16ef250
tools: enable no-extra-semi rule in eslint
targos Jan 15, 2016
f0ee088
lib,test: remove extra semicolons
targos Jan 15, 2016
c6ac464
querystring: improve parse() performance
mscdex Jan 13, 2016
8104d9d
repl: make sure historyPath is trimmed
evanlucas Jan 5, 2016
6988d2e
src: don't check failure with ERR_peek_error()
bnoordhuis Jan 17, 2016
848b04b
node: allow preload modules with -i
evanlucas Jan 14, 2016
4254508
v8,src: expose statistics about heap spaces
bripkens Dec 29, 2015
f221a43
buffer: make byteLength work with Buffer correctly
JacksonTian Jan 18, 2016
d533364
readline: Remove XXX and output debuglog
kohei-takata Jan 15, 2016
3af206d
src: return UV_EAI_NODATA on empty lookup
cjihrig Jan 15, 2016
399db04
test: fix tls-multi-key race condition
santigimeno Nov 22, 2015
14061c6
buffer: remove unnecessary TODO comments
pgeiss Jan 16, 2016
eb2b8c6
module: cache stat() results more aggressively
bnoordhuis Jan 7, 2016
8f4f5b3
tools: enable space-in-parens ESLint rule
silverwind Jan 19, 2016
a39b28b
test: fix issues for space-in-parens ESLint rule
silverwind Jan 19, 2016
a347cd7
test: make test-cluster-disconnect-leak reliable
Trott Jan 18, 2016
426ff82
stream: prevent object map change in ReadableState
evanlucas Jan 19, 2016
8a11b8c
doc: restore ICU third-party software licenses
richardlau Jan 19, 2016
fe23f42
tools: fix license-builder.sh for ICU
richardlau Jan 19, 2016
a2c257a
src: fix negative values in process.hrtime()
bnoordhuis Jan 19, 2016
dd88256
2016-01-20, Version 5.5.0 (Stable)
evanlucas Jan 20, 2016
2d46ea0
Working on v5.5.1
evanlucas Jan 20, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
querystring: improve parse() performance
These changes improve parse() performance from ~11-30% on all of
the existing querystring benchmarks.

PR-URL: #4675
Reviewed-By: Johan Bergström <bugs@bergstroem.nu>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
mscdex authored and evanlucas committed Jan 18, 2016
commit c6ac464dbcfc270d0cd4586fc3dd3f3da69a8119
5 changes: 3 additions & 2 deletions benchmark/querystring/querystring-parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var querystring = require('querystring');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
type: ['noencode', 'encodemany', 'encodelast'],
type: ['noencode', 'encodemany', 'encodelast', 'multivalue'],
n: [1e6],
});

Expand All @@ -14,7 +14,8 @@ function main(conf) {
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];

Expand Down
30 changes: 27 additions & 3 deletions lib/querystring.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) {
return obj;
}

var regexp = /\+/g;
qs = qs.split(sep);

var maxKeys = 1000;
Expand All @@ -230,7 +229,9 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) {

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;

Expand All @@ -242,10 +243,14 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) {
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];
Expand All @@ -256,6 +261,25 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) {
};


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);
Expand Down