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

events: improve removeListener() performance #10572

Merged
merged 1 commit into from
Jan 5, 2017

Conversation

mscdex
Copy link
Contributor

@mscdex mscdex commented Jan 2, 2017

array.shift() seems to be faster than arrayClone() when the item to remove is at the front (at least with V8 5.4).

Comparing the results of the events/ee-add-remove.js benchmark shows ~7% improvement:

                                   improvement significant      p.value
 events/ee-add-remove.js n=2500000      7.25 %         *** 8.925155e-24

NOTE: I have not yet tested array.shift() performance on V8<5.4, so this may/may not be applicable to node versions prior to 7.0.0.

CI: https://ci.nodejs.org/job/node-test-pull-request/5660/

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

@mscdex mscdex added events Issues and PRs related to the events subsystem / EventEmitter. performance Issues and PRs related to the performance of Node.js. labels Jan 2, 2017
@nodejs-github-bot nodejs-github-bot added events Issues and PRs related to the events subsystem / EventEmitter. lts-watch-v6.x labels Jan 2, 2017
@benjamingr
Copy link
Member

benjamingr commented Jan 2, 2017

.splice and .shift use the same code, namely: .shift() is:

  var first = array[0];

  if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
    SparseMove(array, 0, 1, len, 0);
  } else {
    SimpleMove(array, 0, 1, len, 0);
  }

  array.length = len - 1;

  return first;

And splice is:

 if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
    %NormalizeElements(array);
    if (IS_ARRAY(deleted_elements)) %NormalizeElements(deleted_elements);
    SparseSlice(array, start_i, del_count, len, deleted_elements);
    SparseMove(array, start_i, del_count, len, num_elements_to_add);
  } else {
    SimpleSlice(array, start_i, del_count, len, deleted_elements);
    SimpleMove(array, start_i, del_count, len, num_elements_to_add);
  }

We only care about the simple case, so .splice is:

SimpleSlice(array, start_i, del_count, len, deleted_elements);
SimpleMove(array, start_i, del_count, len, num_elements_to_add);

Which should be about the same amount of work given the slice does mostly nothing in this case. That said, .splice has a lot more boilerplate around the implementation.

Anyway - sorry for the storytelling - change LGTM and can confirm the benchmark - just wanted to validate in code.

@benjamingr benjamingr self-requested a review January 2, 2017 17:08
Copy link
Member

@mhdawson mhdawson left a comment

Choose a reason for hiding this comment

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

LGTM

@jasnell
Copy link
Member

jasnell commented Jan 4, 2017

Previous CI run had some red... running again just to make sure: https://ci.nodejs.org/job/node-test-pull-request/5700/

array.shift() seems to be faster than arrayClone() when the item
to remove is at the front (at least with V8 5.4).

PR-URL: nodejs#10572
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
@mscdex mscdex merged commit aab1dd6 into nodejs:master Jan 5, 2017
@mscdex mscdex deleted the events-removelistener-perf branch January 5, 2017 07:57
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 18, 2017
array.shift() seems to be faster than arrayClone() when the item
to remove is at the front (at least with V8 5.4).

PR-URL: nodejs#10572
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 19, 2017
array.shift() seems to be faster than arrayClone() when the item
to remove is at the front (at least with V8 5.4).

PR-URL: nodejs#10572
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 24, 2017
array.shift() seems to be faster than arrayClone() when the item
to remove is at the front (at least with V8 5.4).

PR-URL: nodejs#10572
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
italoacasas pushed a commit to italoacasas/node that referenced this pull request Jan 27, 2017
array.shift() seems to be faster than arrayClone() when the item
to remove is at the front (at least with V8 5.4).

PR-URL: nodejs#10572
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
@italoacasas italoacasas mentioned this pull request Jan 29, 2017
@MylesBorins
Copy link
Contributor

@mscdex how long should this bake before lts?

@MylesBorins MylesBorins added baking-for-lts PRs that need to wait before landing in a LTS release. and removed lts-watch-v4.x labels May 8, 2017
@MylesBorins MylesBorins removed the baking-for-lts PRs that need to wait before landing in a LTS release. label Aug 17, 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. performance Issues and PRs related to the performance of Node.js.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants