lib: micro-optimize url.resolve()
Replace the call to Array#splice() with a faster open-coded version that creates less garbage. Add a new benchmark to prove it. With the change applied, it scores about 5% higher and that is nothing to sneeze at. PR-URL: https://github.com/iojs/io.js/pull/184 Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
This commit is contained in:
parent
6b2af5f0c7
commit
aff56cd2b4
31
benchmark/url/url-resolve.js
Normal file
31
benchmark/url/url-resolve.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
var common = require('../common.js');
|
||||||
|
var url = require('url');
|
||||||
|
var v8 = require('v8');
|
||||||
|
|
||||||
|
var bench = common.createBenchmark(main, {
|
||||||
|
type: ['one'],
|
||||||
|
n: [1e5],
|
||||||
|
});
|
||||||
|
|
||||||
|
function main(conf) {
|
||||||
|
var type = conf.type;
|
||||||
|
var n = conf.n | 0;
|
||||||
|
|
||||||
|
var inputs = {
|
||||||
|
one: ['http://example.com/', '../../../../../etc/passwd'],
|
||||||
|
};
|
||||||
|
var input = inputs[type] || [];
|
||||||
|
|
||||||
|
// Force-optimize url.resolve() so that the benchmark doesn't get
|
||||||
|
// disrupted by the optimizer kicking in halfway through.
|
||||||
|
for (var name in inputs)
|
||||||
|
url.resolve(inputs[name][0], inputs[name][1]);
|
||||||
|
|
||||||
|
v8.setFlagsFromString('--allow_natives_syntax');
|
||||||
|
eval('%OptimizeFunctionOnNextCall(url.resolve)');
|
||||||
|
|
||||||
|
bench.start();
|
||||||
|
for (var i = 0; i < n; i += 1)
|
||||||
|
url.resolve(input[0], input[1]);
|
||||||
|
bench.end(n);
|
||||||
|
}
|
13
lib/url.js
13
lib/url.js
@ -670,12 +670,12 @@ Url.prototype.resolveObject = function(relative) {
|
|||||||
for (var i = srcPath.length; i >= 0; i--) {
|
for (var i = srcPath.length; i >= 0; i--) {
|
||||||
last = srcPath[i];
|
last = srcPath[i];
|
||||||
if (last === '.') {
|
if (last === '.') {
|
||||||
srcPath.splice(i, 1);
|
spliceOne(srcPath, i);
|
||||||
} else if (last === '..') {
|
} else if (last === '..') {
|
||||||
srcPath.splice(i, 1);
|
spliceOne(srcPath, i);
|
||||||
up++;
|
up++;
|
||||||
} else if (up) {
|
} else if (up) {
|
||||||
srcPath.splice(i, 1);
|
spliceOne(srcPath, i);
|
||||||
up--;
|
up--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -750,3 +750,10 @@ Url.prototype.parseHost = function() {
|
|||||||
}
|
}
|
||||||
if (host) this.hostname = host;
|
if (host) this.hostname = host;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// About 1.5x faster than the two-arg version of Array#splice().
|
||||||
|
function spliceOne(list, index) {
|
||||||
|
for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
|
||||||
|
list[i] = list[k];
|
||||||
|
list.pop();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user