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

lib: move duplicate spliceOne into internal/util #16221

Closed
wants to merge 1 commit into from

Conversation

starkwang
Copy link
Contributor

@starkwang starkwang commented Oct 15, 2017

lib/url.js and lib/events.js are using the same spliceOne function.This change is to move it into the internal/util for avoiding duplicate code.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • commit message follows commit guidelines
Affected core subsystem(s)

url, events, util

@nodejs-github-bot nodejs-github-bot added events Issues and PRs related to the events subsystem / EventEmitter. url Issues and PRs related to the legacy built-in url module. util Issues and PRs related to the built-in util module. labels Oct 15, 2017
@vsemozhetbyt
Copy link
Contributor

lib/url.js Outdated
@@ -28,6 +28,8 @@ const { hexTable } = require('internal/querystring');

const errors = require('internal/errors');

var { spliceOne } = require('internal/util');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this module already uses const, maybe we can use const here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@vsemozhetbyt
Copy link
Contributor

Multiple early fails in the CI. Something is temporarily wrong?

@BridgeAR
Copy link
Member

@bmeurer are there plans to optimize splice sometime "soon"?

@starkwang
Copy link
Contributor Author

@bmeurer are there plans to optimize splice sometime "soon"?

And Array.join: https://github.com/nodejs/node/blob/master/lib/internal/util.js#L261

@bmeurer
Copy link
Member

bmeurer commented Oct 15, 2017

We're working on Array#slice, but mostly on the clone case, which should also be usable for Array#splice. Which case is most interesting for Array#splice?

As for Array#join (and Array#toString): One day... hopefully not too far away...

lib/events.js Outdated
@@ -48,6 +48,13 @@ function lazyErrors() {
return errors;
}

var util;
function lazyUtil() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It must have a lazy load here because (#15623):

It is because events.js is loaded before all the other modules in the dependency tree (because of bootstrapping process. Lazy loading errors prevents errors from being loaded before events is loaded.

@starkwang
Copy link
Contributor Author

@vsemozhetbyt Could you please restart a new CI?

@vsemozhetbyt
Copy link
Contributor

lib/events.js Outdated
spliceOne(list, position);
else {
lazyUtil();
util.spliceOne(list, position);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use list.splice(position, 1) here?
This was introduced 3 years ago in d3f8db1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to #14082, it seems like Array#splice is still much slower than spliceOne.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Than I'd rather have the simpler lazy loader, like #14167

var spliceOne;
...
if (!spliceOne) spliceOne = require('internal/util').spliceOne;

@refack
Copy link
Contributor

refack commented Oct 16, 2017

Run a microbenchmark:

> console.time('native'); for (let i = 0; i < 1e8; ++i) { global.x = [1,2,3,4]; global.x.splice(2,1); };console.timeEnd('native')
native: 31554.122ms
> console.time('spliceOne'); for (let i = 0; i < 1e8; ++i) { global.x = [1,2,3,4]; spliceOne(global.x, 2); };console.timeEnd('spliceOne')
spliceOne: 3718.840ms

That shows at ~10x better performance

For url I get it, but IMHO removeListener is not a hot path and is not worth the lazy load mechanics.

lib/events.js Outdated
@@ -416,8 +417,10 @@ EventEmitter.prototype.removeListener =

if (position === 0)
list.shift();
else
else {
spliceOne = spliceOne || require('internal/util').spliceOne;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to write

if (spliceOne === undefined) spliceOne = require('internal/util').spliceOne;

Otherwise there is a type conversion while evalutating if spliceOne is truthy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same code in https://github.com/nodejs/node/blob/master/lib/events.js#L74
Should I rewrite them all?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep it as is to reduce the churn.

Copy link
Member

@apapirovski apapirovski Oct 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Existing code is tricky but when adding new code and we're certain that something is either defined or undefined then a strict comparison is always better.

(Also, for example, domain can be null or undefined and maybe even other falsey values that we don't test for.)

@lpinca
Copy link
Member

lpinca commented Oct 20, 2017

@refack EventEmitter#removeListener() is used extensively in _http_server.js so I'd say it's equally important.

lib/url.js and lib/events.js are using the same spliceOne function.
This change is to move it into the internal/util for avoiding duplicate
code.
@starkwang
Copy link
Contributor Author

Pushed commit to address comment

@refack refack self-assigned this Oct 20, 2017
@refack
Copy link
Contributor

refack commented Oct 20, 2017

@refack
Copy link
Contributor

refack commented Oct 20, 2017

Landed in 7a71cd7

🍾

@refack refack closed this Oct 20, 2017
refack pushed a commit that referenced this pull request Oct 20, 2017
lib/url.js and lib/events.js are using the same spliceOne function.
This change is to move it into the internal/util for avoiding duplicate
code.

PR-URL: #16221
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack
Copy link
Contributor

refack commented Oct 20, 2017

P.S. we should write a benchmark that compares the two so we know when V8 catches up.

@MylesBorins
Copy link
Contributor

This does not land cleanly on the 8.x

Would someone be willing to manually backport?

lpinca pushed a commit to lpinca/node that referenced this pull request Oct 24, 2017
lib/url.js and lib/events.js are using the same spliceOne function.
This change is to move it into the internal/util for avoiding duplicate
code.

PR-URL: nodejs#16221
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
refack pushed a commit to refack/node that referenced this pull request Oct 24, 2017
lib/url.js and lib/events.js are using the same spliceOne function.
This change is to move it into the internal/util for avoiding duplicate
code.

PR-URL: nodejs#16221
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack
Copy link
Contributor

refack commented Oct 24, 2017

Backport PR: #16441

addaleax pushed a commit to ayojs/ayo that referenced this pull request Oct 26, 2017
lib/url.js and lib/events.js are using the same spliceOne function.
This change is to move it into the internal/util for avoiding duplicate
code.

PR-URL: nodejs/node#16221
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
gibfahn pushed a commit that referenced this pull request Oct 30, 2017
lib/url.js and lib/events.js are using the same spliceOne function.
This change is to move it into the internal/util for avoiding duplicate
code.

PR-URL: #16221
Backport-PR-URL: #16433
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
gibfahn pushed a commit that referenced this pull request Oct 31, 2017
lib/url.js and lib/events.js are using the same spliceOne function.
This change is to move it into the internal/util for avoiding duplicate
code.

PR-URL: #16221
Backport-PR-URL: #16433
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@gibfahn gibfahn mentioned this pull request Oct 31, 2017
@MylesBorins
Copy link
Contributor

Should this be backported to v6.x-staging? If yes please follow the guide and raise a backport PR, if not let me know or add the dont-land-on label.

addaleax pushed a commit to ayojs/ayo that referenced this pull request Dec 7, 2017
lib/url.js and lib/events.js are using the same spliceOne function.
This change is to move it into the internal/util for avoiding duplicate
code.

PR-URL: nodejs/node#16221
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack refack removed their assignment Oct 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
events Issues and PRs related to the events subsystem / EventEmitter. url Issues and PRs related to the legacy built-in url module. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging this pull request may close these issues.