-
Notifications
You must be signed in to change notification settings - Fork 30.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
benchmark: improve WHATWG URL benchmarks
* add benchmark to compare the performance of getting url properties between the WHATWG URL and the legacy implementation * add benchmark to compare the performance of serializing urls between the WHATWG URL and the legacy implementation * refactor the benchmark for comparing parsing performance between the two implementations PR-URL: #10678 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
- Loading branch information
1 parent
ecf72d8
commit eac1871
Showing
4 changed files
with
249 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
'use strict'; | ||
const common = require('../common.js'); | ||
const url = require('url'); | ||
const URL = url.URL; | ||
const assert = require('assert'); | ||
|
||
const inputs = { | ||
long: 'http://nodejs.org:89/docs/latest/api/url.html#test?' + | ||
'payload1=true&payload2=false&test=1&benchmark=3&' + | ||
'foo=38.38.011.293&bar=1234834910480&test=19299&3992&' + | ||
'key=f5c65e1e98fe07e648249ad41e1cfdb0', | ||
short: 'https://nodejs.org/en/blog/', | ||
idn: 'http://你好你好', | ||
auth: 'https://user:pass@example.com/path?search=1', | ||
special: 'file:///foo/bar/test/node.js', | ||
percent: 'https://%E4%BD%A0/foo', | ||
dot: 'https://example.org/./a/../b/./c' | ||
}; | ||
|
||
const bench = common.createBenchmark(main, { | ||
type: Object.keys(inputs), | ||
method: ['legacy', 'whatwg'], | ||
n: [1e5] | ||
}); | ||
|
||
// At the time of writing, when using a passed property name to index | ||
// the object, Crankshaft would generate a LoadKeyedGeneric even when it | ||
// remains a constant in the function, so here we must use the literal | ||
// instead to get a LoadNamedField. | ||
function useLegacy(n, input) { | ||
var obj = url.parse(input); | ||
var noDead = { | ||
protocol: obj.protocol, | ||
auth: obj.auth, | ||
host: obj.host, | ||
hostname: obj.hostname, | ||
port: obj.port, | ||
pathname: obj.pathname, | ||
search: obj.search, | ||
hash: obj.hash | ||
}; | ||
// It's necessary to assign the values to an object | ||
// to avoid loop invariant code motion. | ||
bench.start(); | ||
for (var i = 0; i < n; i += 1) { | ||
noDead.protocol = obj.protocol; | ||
noDead.auth = obj.auth; | ||
noDead.host = obj.host; | ||
noDead.hostname = obj.hostname; | ||
noDead.port = obj.port; | ||
noDead.pathname = obj.pathname; | ||
noDead.search = obj.search; | ||
noDead.hash = obj.hash; | ||
} | ||
bench.end(n); | ||
return noDead; | ||
} | ||
|
||
function useWHATWG(n, input) { | ||
var obj = new URL(input); | ||
var noDead = { | ||
protocol: obj.protocol, | ||
auth: obj.username + ':' + obj.password, | ||
host: obj.host, | ||
hostname: obj.hostname, | ||
port: obj.port, | ||
pathname: obj.pathname, | ||
search: obj.search, | ||
hash: obj.hash | ||
}; | ||
bench.start(); | ||
for (var i = 0; i < n; i += 1) { | ||
noDead.protocol = obj.protocol; | ||
noDead.auth = obj.username + ':' + obj.password; | ||
noDead.host = obj.host; | ||
noDead.hostname = obj.hostname; | ||
noDead.port = obj.port; | ||
noDead.pathname = obj.pathname; | ||
noDead.search = obj.search; | ||
noDead.hash = obj.hash; | ||
} | ||
bench.end(n); | ||
return noDead; | ||
} | ||
|
||
function main(conf) { | ||
const type = conf.type; | ||
const n = conf.n | 0; | ||
const method = conf.method; | ||
|
||
const input = inputs[type]; | ||
if (!input) { | ||
throw new Error('Unknown input type'); | ||
} | ||
|
||
var noDead; // Avoid dead code elimination. | ||
switch (method) { | ||
case 'legacy': | ||
noDead = useLegacy(n, input); | ||
break; | ||
case 'whatwg': | ||
noDead = useWHATWG(n, input); | ||
break; | ||
default: | ||
throw new Error('Unknown method'); | ||
} | ||
|
||
assert.ok(noDead); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
'use strict'; | ||
const common = require('../common.js'); | ||
const url = require('url'); | ||
const URL = url.URL; | ||
const assert = require('assert'); | ||
|
||
const inputs = { | ||
long: 'http://nodejs.org:89/docs/latest/api/url.html#test?' + | ||
'payload1=true&payload2=false&test=1&benchmark=3&' + | ||
'foo=38.38.011.293&bar=1234834910480&test=19299&3992&' + | ||
'key=f5c65e1e98fe07e648249ad41e1cfdb0', | ||
short: 'https://nodejs.org/en/blog/', | ||
idn: 'http://你好你好', | ||
auth: 'https://user:pass@example.com/path?search=1', | ||
special: 'file:///foo/bar/test/node.js', | ||
percent: 'https://%E4%BD%A0/foo', | ||
dot: 'https://example.org/./a/../b/./c' | ||
}; | ||
|
||
const bench = common.createBenchmark(main, { | ||
type: Object.keys(inputs), | ||
method: ['legacy', 'whatwg'], | ||
n: [1e5] | ||
}); | ||
|
||
function useLegacy(n, input) { | ||
var noDead = url.parse(input); | ||
bench.start(); | ||
for (var i = 0; i < n; i += 1) { | ||
noDead = url.parse(input); | ||
} | ||
bench.end(n); | ||
return noDead; | ||
} | ||
|
||
function useWHATWG(n, input) { | ||
var noDead = url.parse(input); | ||
bench.start(); | ||
for (var i = 0; i < n; i += 1) { | ||
noDead = new URL(input); | ||
} | ||
bench.end(n); | ||
return noDead; | ||
} | ||
|
||
function main(conf) { | ||
const type = conf.type; | ||
const n = conf.n | 0; | ||
const method = conf.method; | ||
|
||
const input = inputs[type]; | ||
if (!input) { | ||
throw new Error('Unknown input type'); | ||
} | ||
|
||
var noDead; // Avoid dead code elimination. | ||
switch (method) { | ||
case 'legacy': | ||
noDead = useLegacy(n, input); | ||
break; | ||
case 'whatwg': | ||
noDead = useWHATWG(n, input); | ||
break; | ||
default: | ||
throw new Error('Unknown method'); | ||
} | ||
|
||
assert.ok(noDead); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
'use strict'; | ||
const common = require('../common.js'); | ||
const url = require('url'); | ||
const URL = url.URL; | ||
const assert = require('assert'); | ||
|
||
const inputs = { | ||
long: 'http://nodejs.org:89/docs/latest/api/url.html#test?' + | ||
'payload1=true&payload2=false&test=1&benchmark=3&' + | ||
'foo=38.38.011.293&bar=1234834910480&test=19299&3992&' + | ||
'key=f5c65e1e98fe07e648249ad41e1cfdb0', | ||
short: 'https://nodejs.org/en/blog/', | ||
idn: 'http://你好你好', | ||
auth: 'https://user:pass@example.com/path?search=1', | ||
special: 'file:///foo/bar/test/node.js', | ||
percent: 'https://%E4%BD%A0/foo', | ||
dot: 'https://example.org/./a/../b/./c' | ||
}; | ||
|
||
const bench = common.createBenchmark(main, { | ||
type: Object.keys(inputs), | ||
method: ['legacy', 'whatwg'], | ||
n: [1e5] | ||
}); | ||
|
||
function useLegacy(n, input, prop) { | ||
var obj = url.parse(input); | ||
var noDead = url.format(obj); | ||
bench.start(); | ||
for (var i = 0; i < n; i += 1) { | ||
noDead = url.format(obj); | ||
} | ||
bench.end(n); | ||
return noDead; | ||
} | ||
|
||
function useWHATWG(n, input, prop) { | ||
var obj = new URL(input); | ||
var noDead = obj.toString(); | ||
bench.start(); | ||
for (var i = 0; i < n; i += 1) { | ||
noDead = obj.toString(); | ||
} | ||
bench.end(n); | ||
return noDead; | ||
} | ||
|
||
function main(conf) { | ||
const type = conf.type; | ||
const n = conf.n | 0; | ||
const method = conf.method; | ||
|
||
const input = inputs[type]; | ||
if (!input) { | ||
throw new Error('Unknown input type'); | ||
} | ||
|
||
var noDead; // Avoid dead code elimination. | ||
switch (method) { | ||
case 'legacy': | ||
noDead = useLegacy(n, input); | ||
break; | ||
case 'whatwg': | ||
noDead = useWHATWG(n, input); | ||
break; | ||
default: | ||
throw new Error('Unknown method'); | ||
} | ||
|
||
assert.ok(noDead); | ||
} |
This file was deleted.
Oops, something went wrong.