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

Require perf optimization #21300

Closed
wants to merge 38 commits into from
Closed

Require perf optimization #21300

wants to merge 38 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Jun 13, 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

Aim to solve:

Optimize the performance of require one file in a module multiple times

How

Cache a map of the requests and filenames in the parent module

Example

"use strict";

console.time(1);

for(var i = 0; i < 100000; i++){
	require('./require.cpu.empty.js');
}

console.timeEnd(1);

var Module = module.constructor;
var _resolveFilename = Module._resolveFilename

Module._resolveFilename = function(request, parent, isMain, options) {
  var res;
  
  // performance optimize here
  if(parent.resolveFilenameCache){
    if(parent.resolveFilenameCache[request]){
      return parent.resolveFilenameCache[request]
    }
  }else{
  	parent.resolveFilenameCache = {};
  }
  
  res = _resolveFilename(request, parent, isMain, options);
  
  parent.resolveFilenameCache[request] = res;
  
  return res;
}

console.time('2');

for(var i = 0; i < 100000; i++){
	require('./require.cpu.empty.js');
}

console.timeEnd('2');
// result in node V8
1: 1178.783ms
2: 10.344ms

Profile

before:
image
after:
image

Let me know and I'll append some tests or benchmarks if you think it's worth a try.

@apapirovski
Copy link
Contributor

Hi @tswjs, could you explain the use case that this solves that caching it in a local variable doesn't? Thanks.

@ghost
Copy link
Author

ghost commented Jun 13, 2018

Hi @apapirovski , thanks for your reply.
The modules may be different with a change of requests, which means that the developer must maintain a cache map in the code.

const cache = {}

module.exports = (req, res) => {
  for(let i = 0; i < 100000; i++){
    switch (req.url) {
      case 'a':
        cache.a = cache.a ? cache.a : require('a');
        break;
      case 'b':
       cache.b = cache.b ? cache.b : require('b');
       break;
      ...
    }
  }
}

It can solve the problem, but it's really messy code. If the inside cache can solve the problem, people can use require under any circumstances without any concerns. It's a worthy change.

@bnoordhuis
Copy link
Member

There is probably a better way to accomplish this than by adding a new property to the public module.Module object.

If you grep that file for stat.cache, you can find an optimization that we use for caching fs.stat results. You should be able to repurpose that.

eugeneo and others added 24 commits June 14, 2018 16:29
It is now easily accessible from the Environment

Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
The Deprecation cycle explanation in the COLLABORATOR_GUIDE.md file is
now more concise.

PR-URL: #21303
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Pending OpenSSL 1.1.0i release.

PR-URL: #21282
Reviewed-By: Shigeki Ohtsu <ohtsu@ohtsu.org>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Upstream: openssl/openssl@ea7abee

Original commit message:

    Reject excessively large primes in DH key generation.

    CVE-2018-0732

    Signed-off-by: Guido Vranken <guidovranken@gmail.com>

    (cherry picked from commit 91f7361f47b082ae61ffe1a7b17bb2adf213c7fe)

    Reviewed-by: Tim Hudson <tjh@openssl.org>
    Reviewed-by: Matt Caswell <matt@openssl.org>
    (Merged from openssl/openssl#6457)
PR-URL: #21265
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Lance Ball <lball@redhat.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
The old implementation silently failed in EVP_CipherInit_ex in
EVP_CIPH_WRAP_MODE, this commit should fix that.

PR-URL: #21287
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: #21247
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
While `perf_hooks` is still in experimental, remove less useful
bootstrap milestones.

PR-URL: #21247
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Set the thread name for workers in trace events. Also,
use uint64_t for thread_id_ because there's really no
reason for those to be doubles

PR-URL: #21246
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
This change places the links to Writable stream and Readble stream
in the order these sections appear when scrolling down the screen.

PR-URL: #21333
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: Colin Ihrig <cjihrig@gmail.com>
This reverts commit a24b691.

PR-URL: #21363
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
PR-URL: #21361
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: #21361
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Linking URL text to itself is superfluous. It will display as a link in
GitHub anyway. Bonus: This makes it possible to wrap the line at 80
characters.

PR-URL: #21361
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: #21361
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: #21361
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Makefile tasks only lint doc/**/*.md files but omit files that match
doc/*.md. This change adds these previously-omitted files to the list of
files to be linted.

PR-URL: #21361
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
The Buffer doc has a helpful "Class Method" label before static methods
on the Buffer class. The only other class in the docs that I can find
with static methods is ECDH in crypto. Add the label to the one static
method on the ECDH class.

PR-URL: #21357
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
PR-URL: #21311
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: #21367
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Fix a memory leak that occurs with header names that are
short and not present in the static table of default headers.

PR-URL: #21336
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Currently the following compiler warning is reported:
../src/node_stat_watcher.cc:113:13: warning:
unused variable 'argc' [-Wunused-variable]
  const int argc = args.Length();
            ^
1 warning generated.

This commit removes the unused argc variable.

PR-URL: #21337
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: #21256
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
PR-URL: #21273
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matheus Marchini <matheus@sthima.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Remove obsolete wiki references from BUILDING.md.

PR-URL: #21369
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Weijia Wang <starkwang@126.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Trott and others added 3 commits June 17, 2018 21:33
Instead of wording the paragraph about communicating deprecations with
the ecosystem as if it were directed at the ecosystem, write it as in
imperative directed at the collaborator, since that is the audience for
the COLLABORATOR_GUIDE. Instead of assuring the reader that a best
effort will be made, instruct the reader to make the effort to
communicate with the ecosystem.

PR-URL: #21340
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Re-enable `quotes` rule in .eslintrc.js and fix code to abide by the
rule. As a bonus, this makes the code (IMO, anyway) more readable. (It
certainly isn't *less* readable, at least not IMO.)

PR-URL: #21338
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Weijia Wang <starkwang@126.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Don't set `writable` to true when a socket connects if the socket is
already in an ending state.

In the existing code, afterConnect always set `writable` to true.  This
has been the case for a long time, but previous to commit
9b7a691, the socket would still be
destroyed by `destroySoon` and emit a `'close'` event. Since that
commit removed this masking behavior, we have relied on maybeDestroy to
destroy the socket when the readble state is ended, and that won't
happen if `writable` is set to true.

If the socket has `allowHalfOpen` set to true, then `destroy` will still
not be called and `'close'` will not be emitted.

PR-URL: #21290
Fixes: #21268
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@BridgeAR
Copy link
Member

Ping @tswjs

devsnek and others added 3 commits June 18, 2018 09:41
PR-URL: #21354
Reviewed-By: Bradley Farias <bradley.meck@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
The STYLE_GUIDE indicates that personal pronouns like "you" should be
avoided in reference documentation. Remove "you" from N-API doc.

PR-URL: #21382
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Fixes: #18254

PR-URL: #21393
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Yuta Hiroto <hello@hiroppy.me>
@ghost
Copy link
Author

ghost commented Jun 19, 2018

Hi @bnoordhuis , do you mean use the new Map() to store the cache?

@bnoordhuis
Copy link
Member

Something along those lines; be creative. The important point is that it stays internal.

@ghost
Copy link
Author

ghost commented Jun 19, 2018

Got it, I'll modify the code as you say

@ghost ghost closed this Jun 19, 2018
@ghost ghost deleted the require-perf-optimization branch June 19, 2018 13:11
@mapleeit mapleeit restored the require-perf-optimization branch June 19, 2018 13:17
@ghost
Copy link
Author

ghost commented Jun 19, 2018

repurpose: #21404


By the way, do you know how to remove these irrelevant commit history. I tried
git reset --hard where_i_was
git push origin -f

But they are still there. :(

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.