★ wanayoo — archive 1999 https://github.com/nodejs/node/pull/24703Nouvelle recherche | Portail wanayoo
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

url: use SafeSet to filter known special protocols #24703

Closed
wants to merge 1 commit into from

Conversation

Projects
None yet
9 participants
@mikesamuel
Copy link
Contributor

mikesamuel commented Nov 28, 2018 •

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

Avoids a maintenance hazard when reviewers assume that
hostlessProtocol and slashedProtocol are disjoint.

The following may be counter-intuitive:

// These objects seem to have no keys in common
const hostlessProtocol = { 'javascript': true };
const slashedProtocol = { 'http': true };
// A reasonable reviewer may assumes bothTrue is never truthy
function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}
// But
console.log(Boolean(bothTrue('constructor')));  // true

This change uses SafeSet instead of plain-old objects.


Rejected alternative:

We could have used object with a null prototype as lookup tables
so that lowerProto is never treated as a key into Object.prototype.

const hostlessProtocol = { __proto__: null, 'javascript': true };
const slashedProtocol = { __proto__: null, 'http': true };

function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}

console.log(Boolean(bothTrue('constructor')));  // false
@devsnek

This comment has been minimized.

Copy link
Member

devsnek commented Nov 28, 2018

can they just be changed to maps?

@mikesamuel

This comment has been minimized.

Copy link
Contributor Author

mikesamuel commented Nov 28, 2018

@devsnek, They could be changed to Sets. There's no need to lookup a value.

Would you prefer that?

@devsnek

This comment has been minimized.

Copy link
Member

devsnek commented Nov 28, 2018

@mikesamuel i would definitely prefer using sets

@joyeecheung

This comment has been minimized.

Copy link
Member

joyeecheung commented Nov 28, 2018 •

This seems to make the code harder to understand. We usually just go with Object.create(null) if the object is part of a public API, or go with Map if the object is entirely internal. As @mikesamuel pointed out it should be safe to just use a Set so I'd prefer we go with a Set. If one is really feeling paranoid, they can even use the require('internal/safe_gloabls').SafeSet

@lpinca

This comment has been minimized.

Copy link
Member

lpinca commented Nov 28, 2018 •

I think the reason to no use null prototype objects was lookup performance. I don't know if it's still faster.

@mikesamuel

This comment has been minimized.

Copy link
Contributor Author

mikesamuel commented Nov 28, 2018

Reworking to use sets.

@lpinca, Re performance, https://github.com/anvaka/set-vs-object#conclusion is one microbenchmark.

@mikesamuel mikesamuel force-pushed the mikesamuel:patch-1 branch from 68d69d1 to 479068b Nov 28, 2018

@mikesamuel

This comment has been minimized.

Copy link
Contributor Author

mikesamuel commented Nov 28, 2018

I changed it to use SafeSet (thanks @joyeecheung), squashed the commits, and changed the PR description to reflect that.

@mikesamuel

This comment has been minimized.

Copy link
Contributor Author

mikesamuel commented Nov 28, 2018

I think my squash broke Travis's first commit message check :(

@joyeecheung

This comment has been minimized.

Copy link
Member

joyeecheung commented Nov 28, 2018 •

@mikesamuel Can you update the commit message to something that describes the current approach? (e.g. something like url: use SafeSet to filter known special protocols)

url: use SafeSet to filter known special protocols
Avoids a maintenance hazard when reviewers assume that
`hostlessProtocol` and `slashedProtocol` are disjoint.

The following may be counter-intuitive:

```js
// These objects seem to have no keys in common
const hostlessProtocol = { 'javascript': true };
const slashedProtocol = { 'http': true };
// A reasonable reviewer may assumes bothTrue is never truthy
function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}
// But
console.log(Boolean(bothTrue('constructor')));  // true
```

This change uses SafeSet instead of plain-old objects.

----

Rejected alternative:

We could have used object with a `null` prototype as lookup tables
so that `lowerProto` is never treated as a key into `Object.prototype`.

```js
const hostlessProtocol = { __proto__: null, 'javascript': true };
const slashedProtocol = { __proto__: null, 'http': true };

function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}

console.log(Boolean(bothTrue('constructor')));  // false
```

@mikesamuel mikesamuel force-pushed the mikesamuel:patch-1 branch from 479068b to 87677a9 Nov 29, 2018

@mikesamuel

This comment has been minimized.

Copy link
Contributor Author

mikesamuel commented Nov 29, 2018

@joyeecheung, done

@mikesamuel mikesamuel changed the title url: prototypes are not useful in lookup tables url: use SafeSet to filter known special protocols Nov 29, 2018

@joyeecheung

This comment has been minimized.

@Trott

This comment has been minimized.

Copy link
Member

Trott commented Dec 1, 2018

@Trott Trott added the author ready label Dec 1, 2018

@Trott

This comment has been minimized.

Copy link
Member

Trott commented Dec 1, 2018

(Benchmark tradeoffs look perfectly acceptable to me, but second opinion welcome.)

@Trott

This comment has been minimized.

Copy link
Member

Trott commented Dec 1, 2018

Trott added a commit to Trott/io.js that referenced this pull request Dec 1, 2018

url: use SafeSet to filter known special protocols
Avoids a maintenance hazard when reviewers assume that
`hostlessProtocol` and `slashedProtocol` are disjoint.

The following may be counter-intuitive:

```js
// These objects seem to have no keys in common
const hostlessProtocol = { 'javascript': true };
const slashedProtocol = { 'http': true };
// A reasonable reviewer may assumes bothTrue is never truthy
function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}
// But
console.log(Boolean(bothTrue('constructor')));  // true
```

This change uses SafeSet instead of plain-old objects.

----

Rejected alternative:

We could have used object with a `null` prototype as lookup tables
so that `lowerProto` is never treated as a key into `Object.prototype`.

```js
const hostlessProtocol = { __proto__: null, 'javascript': true };
const slashedProtocol = { __proto__: null, 'http': true };

function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}

console.log(Boolean(bothTrue('constructor')));  // false
```

PR-URL: nodejs#24703
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@Trott

This comment has been minimized.

Copy link
Member

Trott commented Dec 1, 2018

Landed in 0d23118.

Thanks for the contribution! 🎉

@Trott Trott closed this Dec 1, 2018

@joyeecheung

This comment has been minimized.

Copy link
Member

joyeecheung commented Dec 1, 2018 •

Post-mortem: benchmark results. The most significant ones (with *** are mostly improvements)

Benchmark results
                                                                                                           confidence improvement accuracy (*)    (**)   (***)
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='auth'                                                      3.06 %       ±7.23%  ±9.62% ±12.54%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='dot'                                                       1.94 %       ±5.87%  ±7.80% ±10.16%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='file'                                                      7.54 %      ±10.54% ±14.03% ±18.26%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='idn'                                                      -0.41 %       ±8.30% ±11.05% ±14.38%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='javascript'                                                1.57 %       ±7.29%  ±9.70% ±12.64%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='long'                                                     -0.94 %      ±10.38% ±13.82% ±17.99%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='percent'                                                  -3.72 %       ±8.28% ±11.02% ±14.34%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='short'                                                    -1.87 %       ±6.14%  ±8.18% ±10.67%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='wpt'                                                      -5.51 %       ±5.73%  ±7.62%  ±9.92%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='legacy' type='ws'                                                        4.73 %      ±10.34% ±13.77% ±17.95%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='auth'                                                      2.97 %       ±6.47%  ±8.63% ±11.27%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='dot'                                                      -0.11 %      ±11.02% ±14.69% ±19.16%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='file'                                                      0.29 %       ±7.57% ±10.08% ±13.11%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='idn'                                                      -3.32 %       ±5.87%  ±7.86% ±10.33%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='javascript'                                               -3.97 %       ±9.63% ±12.82% ±16.68%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='long'                                                      1.61 %       ±7.89% ±10.53% ±13.75%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='percent'                                                   2.45 %       ±8.41% ±11.19% ±14.57%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='short'                                                     1.73 %       ±7.92% ±10.54% ±13.72%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='wpt'                                                      -3.93 %       ±6.77%  ±9.01% ±11.73%
 url/legacy-vs-whatwg-url-get-prop.js e=1 method='whatwg' type='ws'                                                        4.93 %       ±8.46% ±11.26% ±14.66%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='auth' withBase='false'                                        2.12 %       ±8.05% ±10.74% ±14.05%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='auth' withBase='true'                                        -1.03 %       ±6.34%  ±8.43% ±10.98%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='dot' withBase='false'                                        -2.48 %       ±6.93%  ±9.23% ±12.04%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='dot' withBase='true'                                         -0.97 %       ±6.88%  ±9.15% ±11.91%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='file' withBase='false'                                        2.18 %       ±6.97%  ±9.28% ±12.10%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='file' withBase='true'                                         2.31 %       ±7.21%  ±9.59% ±12.48%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='idn' withBase='false'                                         1.26 %       ±7.64% ±10.16% ±13.24%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='idn' withBase='true'                                          2.94 %       ±5.29%  ±7.06%  ±9.21%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='javascript' withBase='false'                                  4.28 %       ±7.85% ±10.48% ±13.73%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='javascript' withBase='true'                                   0.57 %       ±6.67%  ±8.88% ±11.58%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='long' withBase='false'                                        1.60 %       ±5.60%  ±7.46%  ±9.72%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='long' withBase='true'                                        -2.44 %       ±3.87%  ±5.18%  ±6.81%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='percent' withBase='false'                                    -4.06 %       ±8.97% ±11.94% ±15.56%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='percent' withBase='true'                                      3.20 %       ±7.45%  ±9.92% ±12.91%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='short' withBase='false'                                       2.14 %       ±5.29%  ±7.04%  ±9.17%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='short' withBase='true'                                        4.66 %       ±7.99% ±10.63% ±13.84%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='wpt' withBase='false'                                        -2.25 %       ±7.75% ±10.32% ±13.43%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='wpt' withBase='true'                                   *     -5.31 %       ±4.38%  ±5.83%  ±7.60%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='ws' withBase='false'                                          4.99 %       ±7.16%  ±9.57% ±12.53%
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='ws' withBase='true'                                          -5.13 %       ±6.06%  ±8.09% ±10.58%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='auth' withBase='false'                                       -4.43 %       ±7.82% ±10.40% ±13.54%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='auth' withBase='true'                                         2.94 %       ±7.23%  ±9.64% ±12.58%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='dot' withBase='false'                                  *     -6.11 %       ±5.94%  ±7.93% ±10.37%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='dot' withBase='true'                                          0.15 %      ±11.89% ±15.86% ±20.73%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='file' withBase='false'                                       -3.35 %       ±6.27%  ±8.35% ±10.86%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='file' withBase='true'                                        -1.54 %       ±6.93%  ±9.25% ±12.10%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='idn' withBase='false'                                        -3.91 %       ±8.43% ±11.23% ±14.65%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='idn' withBase='true'                                         -4.39 %       ±8.24% ±11.01% ±14.41%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='javascript' withBase='false'                                  1.22 %       ±6.84%  ±9.11% ±11.90%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='javascript' withBase='true'                                   4.17 %       ±6.88%  ±9.15% ±11.91%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='long' withBase='false'                                 *      8.84 %       ±8.76% ±11.71% ±15.35%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='long' withBase='true'                                        -2.62 %       ±7.12%  ±9.49% ±12.38%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='percent' withBase='false'                                     1.09 %       ±9.30% ±12.37% ±16.10%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='percent' withBase='true'                                      2.71 %       ±7.25%  ±9.65% ±12.57%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='short' withBase='false'                                       5.65 %       ±7.10%  ±9.49% ±12.44%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='short' withBase='true'                                       -4.33 %       ±8.15% ±10.87% ±14.20%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='wpt' withBase='false'                                        -0.90 %       ±5.88%  ±7.82% ±10.19%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='wpt' withBase='true'                                          1.01 %       ±6.17%  ±8.21% ±10.69%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='ws' withBase='false'                                         -2.23 %       ±7.11%  ±9.46% ±12.32%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='ws' withBase='true'                                           4.18 %       ±6.25%  ±8.33% ±10.86%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='altspaces'                          1.14 %       ±3.58%  ±4.76%  ±6.20%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='encodefake'                        -0.57 %       ±3.38%  ±4.50%  ±5.86%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='encodelast'                         0.25 %       ±2.46%  ±3.28%  ±4.28%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='encodemany'                        -0.17 %       ±3.84%  ±5.11%  ±6.65%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='manyblankpairs'                    -2.97 %       ±5.77%  ±7.74% ±10.22%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='manypairs'                          1.02 %       ±3.32%  ±4.43%  ±5.78%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='multicharsep'                       0.70 %       ±2.20%  ±2.93%  ±3.81%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='multivalue'                         0.29 %       ±4.29%  ±5.71%  ±7.44%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='multivaluemany'              *     -1.32 %       ±1.15%  ±1.53%  ±1.99%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='noencode'                    *     -2.09 %       ±1.83%  ±2.45%  ±3.20%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='altspaces'                          1.62 %       ±3.41%  ±4.54%  ±5.92%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='encodefake'                        -0.95 %       ±1.11%  ±1.48%  ±1.93%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='encodelast'                        -1.68 %       ±2.05%  ±2.73%  ±3.56%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='encodemany'                         0.89 %       ±4.94%  ±6.58%  ±8.58%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='manyblankpairs'                     0.76 %       ±1.68%  ±2.24%  ±2.93%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='manypairs'                          1.91 %       ±2.85%  ±3.81%  ±5.00%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='multicharsep'                       0.84 %       ±4.72%  ±6.29%  ±8.18%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='multivalue'                         0.30 %       ±5.38%  ±7.16%  ±9.33%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='multivaluemany'                    -0.47 %       ±2.27%  ±3.04%  ±4.01%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='whatwg' searchParam='noencode'                           0.82 %       ±3.49%  ±4.65%  ±6.05%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='altspaces'               *     -3.32 %       ±3.26%  ±4.38%  ±5.76%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='encodefake'                    -1.47 %       ±1.76%  ±2.34%  ±3.05%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='encodelast'                     0.47 %       ±2.71%  ±3.61%  ±4.71%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='encodemany'                    -3.19 %       ±4.14%  ±5.57%  ±7.37%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='manyblankpairs'                -2.27 %       ±4.89%  ±6.50%  ±8.46%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='manypairs'                      0.45 %       ±1.86%  ±2.48%  ±3.24%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='multicharsep'                   0.67 %       ±2.36%  ±3.16%  ±4.16%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='multivalue'                    -0.39 %       ±1.77%  ±2.36%  ±3.07%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='multivaluemany'                 0.61 %       ±2.43%  ±3.24%  ±4.24%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='noencode'                      -1.95 %       ±3.50%  ±4.70%  ±6.21%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='altspaces'                      0.18 %       ±3.22%  ±4.31%  ±5.65%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='encodefake'              *     -1.15 %       ±0.88%  ±1.17%  ±1.52%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='encodelast'                     1.98 %       ±4.56%  ±6.11%  ±8.04%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='encodemany'                     0.07 %       ±1.11%  ±1.48%  ±1.93%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='manyblankpairs'                 3.14 %       ±5.28%  ±7.04%  ±9.19%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='manypairs'                      1.54 %       ±2.28%  ±3.05%  ±4.00%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='multicharsep'                   0.73 %       ±1.43%  ±1.90%  ±2.47%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='multivalue'                    -0.26 %       ±1.43%  ±1.91%  ±2.50%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='multivaluemany'                -0.19 %       ±3.45%  ±4.60%  ±5.99%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='noencode'                      -0.49 %       ±1.36%  ±1.81%  ±2.35%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='auth'                                                    -2.89 %       ±5.68%  ±7.57%  ±9.87%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='dot'                                                      3.66 %       ±5.95%  ±7.92% ±10.33%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='file'                                                     3.40 %       ±6.43%  ±8.55% ±11.13%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='idn'                                                      3.92 %       ±6.18%  ±8.23% ±10.72%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='javascript'                                              -0.29 %       ±7.12%  ±9.47% ±12.33%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='long'                                                    -1.76 %       ±5.54%  ±7.38%  ±9.62%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='percent'                                           *      7.46 %       ±5.91%  ±7.90% ±10.36%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='short'                                                    2.66 %       ±6.89%  ±9.17% ±11.95%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='wpt'                                                      1.73 %       ±6.42%  ±8.55% ±11.13%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='ws'                                                       1.43 %       ±5.65%  ±7.52%  ±9.79%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='auth'                                                     1.66 %       ±6.37%  ±8.49% ±11.08%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='dot'                                                     -2.56 %       ±6.30%  ±8.39% ±10.96%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='file'                                                    -2.45 %       ±5.55%  ±7.40%  ±9.65%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='idn'                                                     -0.95 %       ±5.70%  ±7.59%  ±9.89%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='javascript'                                               1.59 %       ±6.23%  ±8.30% ±10.82%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='long'                                                     2.97 %       ±8.08% ±10.75% ±13.99%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='percent'                                                 -1.31 %       ±4.91%  ±6.55%  ±8.55%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='short'                                                    0.37 %       ±6.92%  ±9.21% ±12.01%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='wpt'                                                      2.01 %       ±5.71%  ±7.61%  ±9.95%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='whatwg' type='ws'                                                       0.78 %       ±6.33%  ±8.42% ±10.96%
 url/url-format.js n=25000000 type='file'                                                                         ***     -5.13 %       ±1.35%  ±1.80%  ±2.34%
 url/url-format.js n=25000000 type='slashes'                                                                               1.89 %       ±2.31%  ±3.08%  ±4.01%
 url/url-parse.js n=10000000 type='escaped'                                                                                0.81 %       ±2.22%  ±2.96%  ±3.85%
 url/url-parse.js n=10000000 type='normal'                                                                                 0.13 %       ±2.83%  ±3.77%  ±4.90%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fauth&y=1999'                                                                       1.63 %       ±4.99%  ±6.64%  ±8.64%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fdot&y=1999'                                                                        0.87 %       ±2.08%  ±2.77%  ±3.60%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Ffile&y=1999'                                                                       1.96 %       ±2.37%  ±3.16%  ±4.12%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fidn&y=1999'                                                                 *      5.19 %       ±4.53%  ±6.06%  ±7.94%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                        ***      3.56 %       ±1.95%  ±2.61%  ±3.41%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Flong&y=1999'                                                                      -0.42 %       ±2.09%  ±2.78%  ±3.62%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fnoscheme&y=1999'                                                                  -1.97 %       ±2.15%  ±2.86%  ±3.72%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fpercent&y=1999'                                                                   -0.73 %       ±4.31%  ±5.77%  ±7.57%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fshort&y=1999'                                                                      1.48 %       ±2.33%  ±3.10%  ±4.04%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fws&y=1999'                                                                         0.66 %       ±2.13%  ±2.83%  ±3.68%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fauth&y=1999'                                                                    1.82 %       ±3.68%  ±4.90%  ±6.40%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fdot&y=1999'                                                                    -0.83 %       ±4.57%  ±6.13%  ±8.07%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Ffile&y=1999'                                                             *      6.01 %       ±5.64%  ±7.57% ±10.00%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fidn&y=1999'                                                                     1.09 %       ±4.21%  ±5.63%  ±7.40%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                      **      4.00 %       ±2.63%  ±3.50%  ±4.56%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Flong&y=1999'                                                                    1.98 %       ±2.97%  ±3.96%  ±5.16%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fnoscheme&y=1999'                                                        **     -3.04 %       ±1.77%  ±2.37%  ±3.11%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fpercent&y=1999'                                                                 3.91 %       ±4.93%  ±6.63%  ±8.76%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fshort&y=1999'                                                            *      5.69 %       ±5.47%  ±7.33%  ±9.63%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fws&y=1999'                                                                      4.13 %       ±6.47%  ±8.64% ±11.30%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fauth&y=1999'                                                                   -1.32 %       ±3.45%  ±4.59%  ±5.97%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fdot&y=1999'                                                                     2.29 %       ±5.88%  ±7.87% ±10.36%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Ffile&y=1999'                                                                    1.98 %       ±4.04%  ±5.40%  ±7.06%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fidn&y=1999'                                                                     2.61 %       ±3.22%  ±4.29%  ±5.59%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                       *      5.84 %       ±4.42%  ±5.94%  ±7.84%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Flong&y=1999'                                                                   -2.23 %       ±3.24%  ±4.31%  ±5.62%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fnoscheme&y=1999'                                                         *     -1.57 %       ±1.38%  ±1.84%  ±2.39%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fpercent&y=1999'                                                                 3.67 %       ±6.53%  ±8.69% ±11.31%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fshort&y=1999'                                                                  -0.80 %       ±3.18%  ±4.25%  ±5.57%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fws&y=1999'                                                                     -3.78 %       ±3.90%  ±5.20%  ±6.78%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fauth&y=1999'                                                                         2.88 %       ±4.43%  ±5.92%  ±7.76%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fdot&y=1999'                                                                          0.38 %       ±2.31%  ±3.08%  ±4.01%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Ffile&y=1999'                                                                         3.15 %       ±3.49%  ±4.68%  ±6.16%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fidn&y=1999'                                                                         -1.19 %       ±3.21%  ±4.28%  ±5.59%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                           **      3.49 %       ±2.31%  ±3.07%  ±4.00%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Flong&y=1999'                                                                        -0.53 %       ±3.42%  ±4.57%  ±6.00%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fnoscheme&y=1999'                                                                    -3.24 %       ±4.38%  ±5.83%  ±7.60%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fpercent&y=1999'                                                                      1.72 %       ±2.54%  ±3.38%  ±4.40%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fshort&y=1999'                                                                        1.92 %       ±4.56%  ±6.06%  ±7.89%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fws&y=1999'                                                                          -4.62 %       ±5.47%  ±7.34%  ±9.68%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fauth&y=1999'                                                                 1.93 %       ±4.82%  ±6.48%  ±8.56%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fdot&y=1999'                                                                  4.20 %       ±4.89%  ±6.52%  ±8.50%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Ffile&y=1999'                                                        ***      8.63 %       ±4.54%  ±6.09%  ±8.03%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fidn&y=1999'                                                                 -0.34 %       ±5.52%  ±7.35%  ±9.58%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                  ***      4.44 %       ±1.93%  ±2.57%  ±3.35%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Flong&y=1999'                                                        ***      8.57 %       ±4.68%  ±6.24%  ±8.15%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fnoscheme&y=1999'                                                             1.18 %       ±2.74%  ±3.68%  ±4.83%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fpercent&y=1999'                                                     ***      8.06 %       ±3.64%  ±4.85%  ±6.33%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fshort&y=1999'                                                       ***      6.61 %       ±3.05%  ±4.08%  ±5.37%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fws&y=1999'                                                                   2.04 %       ±2.53%  ±3.37%  ±4.40%
 url/url-searchparams-iteration.js n=1000000 loopMethod='forEach'                                                         -0.55 %       ±2.71%  ±3.60%  ±4.69%
 url/url-searchparams-iteration.js n=1000000 loopMethod='iterator'                                                         0.78 %       ±2.72%  ±3.62%  ±4.71%
 url/url-searchparams-read.js n=20000000 param='nonexistent' accessMethod='get'                                           -0.58 %       ±4.56%  ±6.08%  ±7.96%
 url/url-searchparams-read.js n=20000000 param='nonexistent' accessMethod='getAll'                                        -1.67 %       ±2.24%  ±3.00%  ±3.95%
 url/url-searchparams-read.js n=20000000 param='nonexistent' accessMethod='has'                                           -0.52 %       ±2.90%  ±3.85%  ±5.01%
 url/url-searchparams-read.js n=20000000 param='one' accessMethod='get'                                                   -0.52 %       ±1.88%  ±2.51%  ±3.26%
 url/url-searchparams-read.js n=20000000 param='one' accessMethod='getAll'                                                 0.62 %       ±1.25%  ±1.67%  ±2.17%
 url/url-searchparams-read.js n=20000000 param='one' accessMethod='has'                                                    1.95 %       ±4.45%  ±5.98%  ±7.92%
 url/url-searchparams-read.js n=20000000 param='three' accessMethod='get'                                                 -2.26 %       ±3.81%  ±5.07%  ±6.61%
 url/url-searchparams-read.js n=20000000 param='three' accessMethod='getAll'                                              -0.32 %       ±1.82%  ±2.42%  ±3.15%
 url/url-searchparams-read.js n=20000000 param='three' accessMethod='has'                                                 -0.89 %       ±4.28%  ±5.69%  ±7.41%
 url/url-searchparams-read.js n=20000000 param='two' accessMethod='get'                                                   -2.43 %       ±3.14%  ±4.21%  ±5.54%
 url/url-searchparams-read.js n=20000000 param='two' accessMethod='getAll'                                                -1.39 %       ±1.70%  ±2.26%  ±2.95%
 url/url-searchparams-read.js n=20000000 param='two' accessMethod='has'                                            **     -2.93 %       ±1.74%  ±2.32%  ±3.02%
 url/url-searchparams-sort.js n=1000000 type='almostsorted'                                                                0.71 %       ±2.12%  ±2.83%  ±3.70%
 url/url-searchparams-sort.js n=1000000 type='empty'                                                                       3.66 %       ±5.33%  ±7.11%  ±9.29%
 url/url-searchparams-sort.js n=1000000 type='long'                                                                        1.11 %       ±2.21%  ±2.96%  ±3.88%
 url/url-searchparams-sort.js n=1000000 type='random'                                                                      0.69 %       ±2.24%  ±2.98%  ±3.89%
 url/url-searchparams-sort.js n=1000000 type='reversed'                                                                    0.02 %       ±1.45%  ±1.93%  ±2.51%
 url/url-searchparams-sort.js n=1000000 type='short'                                                                      -0.10 %       ±3.74%  ±5.00%  ±6.55%
 url/url-searchparams-sort.js n=1000000 type='sorted'                                                                      0.31 %       ±3.45%  ±4.60%  ±6.02%
 url/url-searchparams-sort.js n=1000000 type='wpt'                                                                         1.89 %       ±4.22%  ±5.61%  ±7.31%
 url/usvstring.js n=50000000 input='allinvalid'                                                                           -1.16 %       ±1.59%  ±2.13%  ±2.80%
 url/usvstring.js n=50000000 input='nonstring'                                                                             0.32 %       ±3.45%  ±4.60%  ±5.99%
 url/usvstring.js n=50000000 input='someinvalid'                                                                          -0.32 %       ±0.75%  ±1.00%  ±1.30%
 url/usvstring.js n=50000000 input='valid'                                                                                -0.75 %       ±2.44%  ±3.24%  ±4.22%
 url/usvstring.js n=50000000 input='validsurr'                                                                            -0.73 %       ±0.99%  ±1.32%  ±1.71%
 url/whatwg-url-idna.js n=5000000 to='ascii' domain='all'                                                                  0.28 %       ±3.27%  ±4.36%  ±5.67%
 url/whatwg-url-idna.js n=5000000 to='ascii' domain='empty'                                                               -4.70 %       ±6.19%  ±8.26% ±10.80%
 url/whatwg-url-idna.js n=5000000 to='ascii' domain='none'                                                                -0.79 %       ±2.07%  ±2.75%  ±3.59%
 url/whatwg-url-idna.js n=5000000 to='ascii' domain='nonstring'                                                           -0.43 %       ±2.67%  ±3.56%  ±4.65%
 url/whatwg-url-idna.js n=5000000 to='ascii' domain='some'                                                                 0.48 %       ±2.40%  ±3.20%  ±4.16%
 url/whatwg-url-idna.js n=5000000 to='unicode' domain='all'                                                               -0.05 %       ±0.88%  ±1.18%  ±1.53%
 url/whatwg-url-idna.js n=5000000 to='unicode' domain='empty'                                                              2.78 %       ±5.31%  ±7.09%  ±9.30%
 url/whatwg-url-idna.js n=5000000 to='unicode' domain='none'                                                               0.22 %       ±2.74%  ±3.65%  ±4.75%
 url/whatwg-url-idna.js n=5000000 to='unicode' domain='nonstring'                                                          1.72 %       ±2.63%  ±3.51%  ±4.56%
 url/whatwg-url-idna.js n=5000000 to='unicode' domain='some'                                                               0.42 %       ±1.26%  ±1.68%  ±2.20%
 url/whatwg-url-properties.js prop='hash' e=1 type='wpt' withBase='false'                                                  0.24 %       ±5.53%  ±7.35%  ±9.57%
 url/whatwg-url-properties.js prop='hash' e=1 type='wpt' withBase='true'                                                  -6.65 %       ±7.63% ±10.15% ±13.21%
 url/whatwg-url-properties.js prop='host' e=1 type='wpt' withBase='false'                                                  1.27 %       ±3.93%  ±5.23%  ±6.80%
 url/whatwg-url-properties.js prop='host' e=1 type='wpt' withBase='true'                                                   0.04 %       ±7.28%  ±9.70% ±12.65%
 url/whatwg-url-properties.js prop='hostname' e=1 type='wpt' withBase='false'                                             -3.24 %       ±6.84%  ±9.13% ±11.92%
 url/whatwg-url-properties.js prop='hostname' e=1 type='wpt' withBase='true'                                              -0.56 %       ±6.71%  ±8.94% ±11.66%
 url/whatwg-url-properties.js prop='href' e=1 type='wpt' withBase='false'                                                 -0.94 %       ±4.89%  ±6.51%  ±8.48%
 url/whatwg-url-properties.js prop='href' e=1 type='wpt' withBase='true'                                                  -3.40 %       ±7.63% ±10.15% ±13.22%
 url/whatwg-url-properties.js prop='origin' e=1 type='wpt' withBase='false'                                               -0.36 %       ±7.54% ±10.04% ±13.07%
 url/whatwg-url-properties.js prop='origin' e=1 type='wpt' withBase='true'                                                -5.37 %       ±7.29%  ±9.70% ±12.63%
 url/whatwg-url-properties.js prop='password' e=1 type='wpt' withBase='false'                                             -1.59 %       ±4.22%  ±5.63%  ±7.35%
 url/whatwg-url-properties.js prop='password' e=1 type='wpt' withBase='true'                                               1.26 %       ±8.33% ±11.10% ±14.48%
 url/whatwg-url-properties.js prop='pathname' e=1 type='wpt' withBase='false'                                              1.72 %       ±4.95%  ±6.61%  ±8.67%
 url/whatwg-url-properties.js prop='pathname' e=1 type='wpt' withBase='true'                                              -3.37 %       ±8.74% ±11.63% ±15.14%
 url/whatwg-url-properties.js prop='port' e=1 type='wpt' withBase='false'                                                  3.10 %       ±6.05%  ±8.05% ±10.48%
 url/whatwg-url-properties.js prop='port' e=1 type='wpt' withBase='true'                                                   7.47 %       ±9.21% ±12.26% ±15.96%
 url/whatwg-url-properties.js prop='protocol' e=1 type='wpt' withBase='false'                                             -3.92 %       ±5.21%  ±6.93%  ±9.03%
 url/whatwg-url-properties.js prop='protocol' e=1 type='wpt' withBase='true'                                              -2.14 %       ±7.93% ±10.56% ±13.74%
 url/whatwg-url-properties.js prop='search' e=1 type='wpt' withBase='false'                                               -3.06 %       ±6.39%  ±8.50% ±11.08%
 url/whatwg-url-properties.js prop='search' e=1 type='wpt' withBase='true'                                                -1.01 %       ±6.44%  ±8.57% ±11.16%
 url/whatwg-url-properties.js prop='searchParams' e=1 type='wpt' withBase='false'                                         -3.26 %       ±4.76%  ±6.34%  ±8.25%
 url/whatwg-url-properties.js prop='searchParams' e=1 type='wpt' withBase='true'                                           2.91 %       ±8.22% ±10.95% ±14.29%
 url/whatwg-url-properties.js prop='username' e=1 type='wpt' withBase='false'                                      **      7.86 %       ±4.88%  ±6.51%  ±8.51%
 url/whatwg-url-properties.js prop='username' e=1 type='wpt' withBase='true'                                              -0.37 %       ±7.47%  ±9.94% ±12.96%

Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case there are 235 comparisons, you can thus
expect the following amount of false-positive results:
  11.75 false positives, when considering a   5% risk acceptance (*, **, ***),
  2.35 false positives, when considering a   1% risk acceptance (**, ***),
  0.24 false positives, when considering a 0.1% risk acceptance (***)
Notifying upstream projects of job completion
Finished: SUCCESS

Significant impact
                                                                                                           confidence improvement accuracy (*)    (**)   (***)
 url/legacy-vs-whatwg-url-parse.js method='legacy' e=1 type='wpt' withBase='true'                                   *     -5.31 %       ±4.38%  ±5.83%  ±7.60%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='dot' withBase='false'                                  *     -6.11 %       ±5.94%  ±7.93% ±10.37%
 url/legacy-vs-whatwg-url-parse.js method='whatwg' e=1 type='long' withBase='false'                                 *      8.84 %       ±8.76% ±11.71% ±15.35%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='multivaluemany'              *     -1.32 %       ±1.15%  ±1.53%  ±1.99%
 url/legacy-vs-whatwg-url-searchparams-parse.js n=1000000 method='legacy' searchParam='noencode'                    *     -2.09 %       ±1.83%  ±2.45%  ±3.20%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='legacy' searchParam='altspaces'               *     -3.32 %       ±3.26%  ±4.38%  ±5.76%
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method='whatwg' searchParam='encodefake'              *     -1.15 %       ±0.88%  ±1.17%  ±1.52%
 url/legacy-vs-whatwg-url-serialize.js e=1 method='legacy' type='percent'                                           *      7.46 %       ±5.91%  ±7.90% ±10.36%
 url/url-format.js n=25000000 type='file'                                                                         ***     -5.13 %       ±1.35%  ±1.80%  ±2.34%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fidn&y=1999'                                                                 *      5.19 %       ±4.53%  ±6.06%  ±7.94%
 url/url-resolve.js n=100000 path='down' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                        ***      3.56 %       ±1.95%  ±2.61%  ±3.41%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Ffile&y=1999'                                                             *      6.01 %       ±5.64%  ±7.57% ±10.00%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                      **      4.00 %       ±2.63%  ±3.50%  ±4.56%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fnoscheme&y=1999'                                                        **     -3.04 %       ±1.77%  ±2.37%  ±3.11%
 url/url-resolve.js n=100000 path='foo/bar' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fshort&y=1999'                                                            *      5.69 %       ±5.47%  ±7.33%  ±9.63%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                       *      5.84 %       ±4.42%  ±5.94%  ±7.84%
 url/url-resolve.js n=100000 path='sibling' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fnoscheme&y=1999'                                                         *     -1.57 %       ±1.38%  ±1.84%  ±2.39%
 url/url-resolve.js n=100000 path='up' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                           **      3.49 %       ±2.31%  ±3.07%  ±4.00%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Ffile&y=1999'                                                        ***      8.63 %       ±4.54%  ±6.09%  ±8.03%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fjavascript&y=1999'                                                  ***      4.44 %       ±1.93%  ±2.57%  ±3.35%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Flong&y=1999'                                                        ***      8.57 %       ±4.68%  ±6.24%  ±8.15%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fpercent&y=1999'                                                     ***      8.06 %       ±3.64%  ±4.85%  ±6.33%
 url/url-resolve.js n=100000 path='withscheme' href='/old?u=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fpull%2Fshort&y=1999'                                                       ***      6.61 %       ±3.05%  ±4.08%  ±5.37%
 url/url-searchparams-read.js n=20000000 param='two' accessMethod='has'                                            **     -2.93 %       ±1.74%  ±2.32%  ±3.02%
 url/whatwg-url-properties.js prop='username' e=1 type='wpt' withBase='false'                                      **      7.86 %       ±4.88%  ±6.51%  ±8.51%

BridgeAR added a commit that referenced this pull request Dec 5, 2018

url: use SafeSet to filter known special protocols
Avoids a maintenance hazard when reviewers assume that
`hostlessProtocol` and `slashedProtocol` are disjoint.

The following may be counter-intuitive:

```js
// These objects seem to have no keys in common
const hostlessProtocol = { 'javascript': true };
const slashedProtocol = { 'http': true };
// A reasonable reviewer may assumes bothTrue is never truthy
function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}
// But
console.log(Boolean(bothTrue('constructor')));  // true
```

This change uses SafeSet instead of plain-old objects.

----

Rejected alternative:

We could have used object with a `null` prototype as lookup tables
so that `lowerProto` is never treated as a key into `Object.prototype`.

```js
const hostlessProtocol = { __proto__: null, 'javascript': true };
const slashedProtocol = { __proto__: null, 'http': true };

function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}

console.log(Boolean(bothTrue('constructor')));  // false
```

PR-URL: #24703
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

@BridgeAR BridgeAR referenced this pull request Dec 5, 2018

Merged

v11.4.0 proposal #24854

4 of 4 tasks complete

refack added a commit to refack/node that referenced this pull request Jan 14, 2019

url: use SafeSet to filter known special protocols
Avoids a maintenance hazard when reviewers assume that
`hostlessProtocol` and `slashedProtocol` are disjoint.

The following may be counter-intuitive:

```js
// These objects seem to have no keys in common
const hostlessProtocol = { 'javascript': true };
const slashedProtocol = { 'http': true };
// A reasonable reviewer may assumes bothTrue is never truthy
function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}
// But
console.log(Boolean(bothTrue('constructor')));  // true
```

This change uses SafeSet instead of plain-old objects.

----

Rejected alternative:

We could have used object with a `null` prototype as lookup tables
so that `lowerProto` is never treated as a key into `Object.prototype`.

```js
const hostlessProtocol = { __proto__: null, 'javascript': true };
const slashedProtocol = { __proto__: null, 'http': true };

function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}

console.log(Boolean(bothTrue('constructor')));  // false
```

PR-URL: nodejs#24703
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

BethGriggs added a commit that referenced this pull request Feb 12, 2019

url: use SafeSet to filter known special protocols
Avoids a maintenance hazard when reviewers assume that
`hostlessProtocol` and `slashedProtocol` are disjoint.

The following may be counter-intuitive:

```js
// These objects seem to have no keys in common
const hostlessProtocol = { 'javascript': true };
const slashedProtocol = { 'http': true };
// A reasonable reviewer may assumes bothTrue is never truthy
function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}
// But
console.log(Boolean(bothTrue('constructor')));  // true
```

This change uses SafeSet instead of plain-old objects.

----

Rejected alternative:

We could have used object with a `null` prototype as lookup tables
so that `lowerProto` is never treated as a key into `Object.prototype`.

```js
const hostlessProtocol = { __proto__: null, 'javascript': true };
const slashedProtocol = { __proto__: null, 'http': true };

function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}

console.log(Boolean(bothTrue('constructor')));  // false
```

PR-URL: #24703
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

@BethGriggs BethGriggs referenced this pull request Feb 12, 2019

Merged

v10.15.3 proposal #26063

rvagg added a commit that referenced this pull request Feb 28, 2019

url: use SafeSet to filter known special protocols
Avoids a maintenance hazard when reviewers assume that
`hostlessProtocol` and `slashedProtocol` are disjoint.

The following may be counter-intuitive:

```js
// These objects seem to have no keys in common
const hostlessProtocol = { 'javascript': true };
const slashedProtocol = { 'http': true };
// A reasonable reviewer may assumes bothTrue is never truthy
function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}
// But
console.log(Boolean(bothTrue('constructor')));  // true
```

This change uses SafeSet instead of plain-old objects.

----

Rejected alternative:

We could have used object with a `null` prototype as lookup tables
so that `lowerProto` is never treated as a key into `Object.prototype`.

```js
const hostlessProtocol = { __proto__: null, 'javascript': true };
const slashedProtocol = { __proto__: null, 'http': true };

function bothTrue(lowerProto) {
  return hostlessProtocol[lowerProto] && slashedProtocol[lowerProto];
}

console.log(Boolean(bothTrue('constructor')));  // false
```

PR-URL: #24703
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.