aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2017-01-11 01:38:59 +0800
committerJoyee Cheung <joyeec9h3@gmail.com>2017-01-15 20:26:19 +0800
commitd4b749b62f6c126349dda6be38a9a6d68d851b06 (patch)
tree8d3a59de4aad884a71d44b02f061d3c2d1858b1f
parent97f001ab167875c8e8e8418fa55ff14ef76a4064 (diff)
downloadandroid-node-v8-d4b749b62f6c126349dda6be38a9a6d68d851b06.tar.gz
android-node-v8-d4b749b62f6c126349dda6be38a9a6d68d851b06.tar.bz2
android-node-v8-d4b749b62f6c126349dda6be38a9a6d68d851b06.zip
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: https://github.com/nodejs/node/pull/10678 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
-rw-r--r--benchmark/url/legacy-vs-whatwg-url-get-prop.js109
-rw-r--r--benchmark/url/legacy-vs-whatwg-url-parse.js69
-rw-r--r--benchmark/url/legacy-vs-whatwg-url-serialize.js71
-rw-r--r--benchmark/url/new-url-parse.js57
4 files changed, 249 insertions, 57 deletions
diff --git a/benchmark/url/legacy-vs-whatwg-url-get-prop.js b/benchmark/url/legacy-vs-whatwg-url-get-prop.js
new file mode 100644
index 0000000000..f703b75b16
--- /dev/null
+++ b/benchmark/url/legacy-vs-whatwg-url-get-prop.js
@@ -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);
+}
diff --git a/benchmark/url/legacy-vs-whatwg-url-parse.js b/benchmark/url/legacy-vs-whatwg-url-parse.js
new file mode 100644
index 0000000000..ca7a48466c
--- /dev/null
+++ b/benchmark/url/legacy-vs-whatwg-url-parse.js
@@ -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);
+}
diff --git a/benchmark/url/legacy-vs-whatwg-url-serialize.js b/benchmark/url/legacy-vs-whatwg-url-serialize.js
new file mode 100644
index 0000000000..c0b7f5a6ce
--- /dev/null
+++ b/benchmark/url/legacy-vs-whatwg-url-serialize.js
@@ -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);
+}
diff --git a/benchmark/url/new-url-parse.js b/benchmark/url/new-url-parse.js
deleted file mode 100644
index ef60e81847..0000000000
--- a/benchmark/url/new-url-parse.js
+++ /dev/null
@@ -1,57 +0,0 @@
-'use strict';
-const common = require('../common.js');
-const url = require('url');
-const v8 = require('v8');
-
-const bench = common.createBenchmark(main, {
- type: 'one two three four five'.split(' '),
- method: ['old', 'new'],
- n: [25e4]
-});
-
-function useOld(n, input) {
- // Force-optimize url.parse() so that the benchmark doesn't get
- // disrupted by the optimizer kicking in halfway through.
- url.parse(input);
- v8.setFlagsFromString('--allow_natives_syntax');
- eval('%OptimizeFunctionOnNextCall(url.parse)');
-
- bench.start();
- for (var i = 0; i < n; i += 1)
- url.parse(input);
- bench.end(n);
-}
-
-function useNew(n, input) {
- bench.start();
- for (var i = 0; i < n; i += 1)
- new url.URL(input);
- bench.end(n);
-}
-
-function main(conf) {
- const type = conf.type;
- const n = conf.n | 0;
- const method = conf.method;
-
- var inputs = {
- one: 'http://nodejs.org/docs/latest/api/url.html#url_url_format_urlobj',
- two: 'http://blog.nodejs.org/',
- three: 'https://encrypted.google.com/search?q=url&q=site:npmjs.org&hl=en',
- four: 'javascript:alert("node is awesome");',
- //five: 'some.ran/dom/url.thing?oh=yes#whoo',
- five: 'https://user:pass@example.com/',
- };
- var input = inputs[type] || '';
-
- switch (method) {
- case 'old':
- useOld(n, input);
- break;
- case 'new':
- useNew(n, input);
- break;
- default:
- throw new Error('Unknown method');
- }
-}