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

src: replace pushValueToArray with pure C++ API #24125

Closed
wants to merge 4 commits into from

Conversation

joyeecheung
Copy link
Member

@joyeecheung joyeecheung commented Nov 6, 2018

The first commit just landed upstream: https://chromium-review.googlesource.com/c/1317049
The second commit replaces the pushValueToArray hack with the new V8 API in fs.readdir and fs.readdirSync.
The third commit added more options to the readdir benchmark.

Local benchmark results:

                                                                        confidence improvement accuracy (*)   (**)  (***)
 fs/bench-readdir.js withFileTypes='false' dir='lib' n=10                              -0.33 %       ±4.75% ±6.33% ±8.26%
 fs/bench-readdir.js withFileTypes='false' dir='test/parallel' n=10            ***      8.96 %       ±2.83% ±3.78% ±4.93%
 fs/bench-readdir.js withFileTypes='true' dir='lib' n=10                                0.17 %       ±4.36% ±5.80% ±7.56%
 fs/bench-readdir.js withFileTypes='true' dir='test/parallel' n=10                      0.53 %       ±2.37% ±3.16% ±4.11%
 fs/bench-readdirSync.js withFileTypes='false' dir='lib' n=10                  ***      6.21 %       ±3.41% ±4.56% ±5.97%
 fs/bench-readdirSync.js withFileTypes='false' dir='test/parallel' n=10        ***     13.29 %       ±2.35% ±3.13% ±4.08%
 fs/bench-readdirSync.js withFileTypes='true' dir='lib' n=10                   ***      6.27 %       ±1.81% ±2.41% ±3.15%
 fs/bench-readdirSync.js withFileTypes='true' dir='test/parallel' n=10         ***      9.88 %       ±2.51% ±3.34% ±4.35%

With this I hope we can remove all the push_values_to_array_function usage and get rid of SetupProcessObject eventually - that can be done in later PRs, of course.

deps: cherry-pick 0483e9a from upstream V8

Original commit message:

[api] Allow embedder to construct an Array from Local<Value>*

Currently to obtain a v8::Array out of a C array or a std::vector,
one needs to loop through the elements and call array->Set() multiple
times, and these calls go into v8::Object::Set() which can be slow.
This patch adds a new Array::New overload that converts a
Local<Value>* with known size into a Local<Array>.

Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188
Reviewed-on: https://chromium-review.googlesource.com/c/1317049
Reviewed-by: Yang Guo <yangguo@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/master@{#57261}

Refs: v8/v8@0483e9a

fs: replace pushValueToArray with pure C++ API

Instead of calling into JS from C++ to push values into an array,
use the new Array::New API that takes a pointer and a length
directly.

benchmark: add dir and withFileTypes option readdir benchmarks

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

Original commit message:

    [api] Allow embedder to construct an Array from Local<Value>*

    Currently to obtain a v8::Array out of a C array or a std::vector,
    one needs to loop through the elements and call array->Set() multiple
    times, and these calls go into v8::Object::Set() which can be slow.
    This patch adds a new Array::New overload that converts a
    Local<Value>* with known size into a Local<Array>.

    Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188
    Reviewed-on: https://chromium-review.googlesource.com/c/1317049
    Reviewed-by: Yang Guo <yangguo@chromium.org>
    Reviewed-by: Adam Klein <adamk@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Cr-Commit-Position: refs/heads/master@{#57261}

Refs: v8/v8@0483e9a
Instead of calling into JS from C++ to push values into an array,
use the new Array::New API that takes a pointer and a length
directly.
@nodejs-github-bot nodejs-github-bot added the lib / src Issues and PRs related to general changes in the lib or src directory. label Nov 6, 2018
@joyeecheung
Copy link
Member Author

joyeecheung commented Nov 6, 2018

From the Benchmark CI:

Benchmark results
                                                                        confidence improvement accuracy (*)   (**)   (***)
 fs/bench-readdir.js withFileTypes='false' dir='lib' n=10                       **      4.16 %       ±2.84% ±3.78%  ±4.92%
 fs/bench-readdir.js withFileTypes='false' dir='test/parallel' n=10            ***     16.63 %       ±2.50% ±3.32%  ±4.33%
 fs/bench-readdir.js withFileTypes='true' dir='lib' n=10                        **      4.58 %       ±3.15% ±4.20%  ±5.49%
 fs/bench-readdir.js withFileTypes='true' dir='test/parallel' n=10             ***     12.46 %       ±2.22% ±2.96%  ±3.86%
 fs/bench-readdirSync.js withFileTypes='false' dir='lib' n=10                           6.01 %       ±7.39% ±9.84% ±12.81%
 fs/bench-readdirSync.js withFileTypes='false' dir='test/parallel' n=10        ***     18.95 %       ±5.27% ±7.02%  ±9.17%
 fs/bench-readdirSync.js withFileTypes='true' dir='lib' n=10                     *      5.94 %       ±5.64% ±7.51%  ±9.77%
 fs/bench-readdirSync.js withFileTypes='true' dir='test/parallel' n=10         ***     14.33 %       ±4.42% ±5.89%  ±7.68%

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

Significant impact
                                                                        confidence improvement accuracy (*)   (**)   (***)
 fs/bench-readdir.js withFileTypes='false' dir='lib' n=10                       **      4.16 %       ±2.84% ±3.78%  ±4.92%
 fs/bench-readdir.js withFileTypes='false' dir='test/parallel' n=10            ***     16.63 %       ±2.50% ±3.32%  ±4.33%
 fs/bench-readdir.js withFileTypes='true' dir='lib' n=10                        **      4.58 %       ±3.15% ±4.20%  ±5.49%
 fs/bench-readdir.js withFileTypes='true' dir='test/parallel' n=10             ***     12.46 %       ±2.22% ±2.96%  ±3.86%
 fs/bench-readdirSync.js withFileTypes='false' dir='test/parallel' n=10        ***     18.95 %       ±5.27% ±7.02%  ±9.17%
 fs/bench-readdirSync.js withFileTypes='true' dir='lib' n=10                     *      5.94 %       ±5.64% ±7.51%  ±9.77%
 fs/bench-readdirSync.js withFileTypes='true' dir='test/parallel' n=10         ***     14.33 %       ±4.42% ±5.89%  ±7.68%

@joyeecheung joyeecheung added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Nov 6, 2018
Copy link
Member

@bnoordhuis bnoordhuis left a comment

Choose a reason for hiding this comment

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

LGTM with suggestions. Nice work.

bench.start();
(function r(cntr) {
if (cntr-- <= 0)
return bench.end(n);
fs.readdir(path.resolve(__dirname, '../../lib/'), function() {
const fullPath = path.resolve(__dirname, '../../', dir);
Copy link
Member

Choose a reason for hiding this comment

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

Maybe something for a separate commit or PR but you could move this to before the bench.start() call. The fewer tangents the benchmark has, the better.

(Ditto in the other file.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, thanks for spotting this! (Pretty sure I made a change for that before, somehow it got lost before I opened the PR..)

result->Set(0, names);
result->Set(1, types);
result->Set(0, Array::New(isolate, name_v.data(), name_v.size()));
result->Set(1, Array::New(isolate, type_v.data(), type_v.size()));
Copy link
Member

Choose a reason for hiding this comment

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

You could improve on this a little by returning a single names+types array. You also need to update getDirents() in lib/internal/fs/utils.js if you do, but that should be straightforward.

Copy link
Member Author

Choose a reason for hiding this comment

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

@bnoordhuis Good idea, though I'd rather leave that as a follow-up

@joyeecheung
Copy link
Member Author

(The CI seems silent, so hopefully I am not getting in the way of code and learn): I don't think I could break anything with the fixup but anyway another CI https://ci.nodejs.org/job/node-test-pull-request/18377/

Copy link
Contributor

@refack refack left a comment

Choose a reason for hiding this comment

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

🎉

Trott pushed a commit to Trott/io.js that referenced this pull request Nov 8, 2018
Original commit message:

    [api] Allow embedder to construct an Array from Local<Value>*

    Currently to obtain a v8::Array out of a C array or a std::vector,
    one needs to loop through the elements and call array->Set() multiple
    times, and these calls go into v8::Object::Set() which can be slow.
    This patch adds a new Array::New overload that converts a
    Local<Value>* with known size into a Local<Array>.

    Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188
    Reviewed-on: https://chromium-review.googlesource.com/c/1317049
    Reviewed-by: Yang Guo <yangguo@chromium.org>
    Reviewed-by: Adam Klein <adamk@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Cr-Commit-Position: refs/heads/master@{#57261}

Refs: v8/v8@0483e9a

PR-URL: nodejs#24125
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Trott pushed a commit to Trott/io.js that referenced this pull request Nov 8, 2018
Instead of calling into JS from C++ to push values into an array,
use the new Array::New API that takes a pointer and a length
directly.

PR-URL: nodejs#24125
Refs: v8/v8@0483e9a
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Trott pushed a commit to Trott/io.js that referenced this pull request Nov 8, 2018
PR-URL: nodejs#24125
Refs: v8/v8@0483e9a
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@Trott
Copy link
Member

Trott commented Nov 8, 2018

Landed in 7d86a53...ca51b94

@Trott Trott closed this Nov 8, 2018
@refack refack added landed and removed author ready PRs that have at least one approval, no pending requests for changes, and a CI started. labels Nov 8, 2018
BridgeAR pushed a commit that referenced this pull request Nov 14, 2018
Original commit message:

    [api] Allow embedder to construct an Array from Local<Value>*

    Currently to obtain a v8::Array out of a C array or a std::vector,
    one needs to loop through the elements and call array->Set() multiple
    times, and these calls go into v8::Object::Set() which can be slow.
    This patch adds a new Array::New overload that converts a
    Local<Value>* with known size into a Local<Array>.

    Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188
    Reviewed-on: https://chromium-review.googlesource.com/c/1317049
    Reviewed-by: Yang Guo <yangguo@chromium.org>
    Reviewed-by: Adam Klein <adamk@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Cr-Commit-Position: refs/heads/master@{#57261}

Refs: v8/v8@0483e9a

PR-URL: #24125
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
BridgeAR pushed a commit that referenced this pull request Nov 14, 2018
Instead of calling into JS from C++ to push values into an array,
use the new Array::New API that takes a pointer and a length
directly.

PR-URL: #24125
Refs: v8/v8@0483e9a
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
BridgeAR pushed a commit that referenced this pull request Nov 14, 2018
PR-URL: #24125
Refs: v8/v8@0483e9a
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
kiyomizumia pushed a commit to kiyomizumia/node that referenced this pull request Nov 15, 2018
Original commit message:

    [api] Allow embedder to construct an Array from Local<Value>*

    Currently to obtain a v8::Array out of a C array or a std::vector,
    one needs to loop through the elements and call array->Set() multiple
    times, and these calls go into v8::Object::Set() which can be slow.
    This patch adds a new Array::New overload that converts a
    Local<Value>* with known size into a Local<Array>.

    Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188
    Reviewed-on: https://chromium-review.googlesource.com/c/1317049
    Reviewed-by: Yang Guo <yangguo@chromium.org>
    Reviewed-by: Adam Klein <adamk@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Cr-Commit-Position: refs/heads/master@{#57261}

Refs: v8/v8@0483e9a

PR-URL: nodejs#24125
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
kiyomizumia pushed a commit to kiyomizumia/node that referenced this pull request Nov 15, 2018
Instead of calling into JS from C++ to push values into an array,
use the new Array::New API that takes a pointer and a length
directly.

PR-URL: nodejs#24125
Refs: v8/v8@0483e9a
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
kiyomizumia pushed a commit to kiyomizumia/node that referenced this pull request Nov 15, 2018
PR-URL: nodejs#24125
Refs: v8/v8@0483e9a
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@hiroppy hiroppy mentioned this pull request Nov 24, 2018
62 tasks
@kt3k kt3k mentioned this pull request Nov 24, 2018
2 tasks
kazupon added a commit to kazupon/node that referenced this pull request Nov 24, 2018
@kazupon kazupon mentioned this pull request Nov 24, 2018
4 tasks
gireeshpunathil pushed a commit that referenced this pull request Nov 26, 2018
replace with C++ API.

Refs: #24125
PR-URL: #24614
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
targos pushed a commit that referenced this pull request Nov 27, 2018
replace with C++ API.

Refs: #24125
PR-URL: #24614
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
rvagg pushed a commit that referenced this pull request Nov 28, 2018
replace with C++ API.

Refs: #24125
PR-URL: #24614
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
targos pushed a commit to targos/node that referenced this pull request Dec 4, 2018
Original commit message:

    [api] Allow embedder to construct an Array from Local<Value>*

    Currently to obtain a v8::Array out of a C array or a std::vector,
    one needs to loop through the elements and call array->Set() multiple
    times, and these calls go into v8::Object::Set() which can be slow.
    This patch adds a new Array::New overload that converts a
    Local<Value>* with known size into a Local<Array>.

    Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188
    Reviewed-on: https://chromium-review.googlesource.com/c/1317049
    Reviewed-by: Yang Guo <yangguo@chromium.org>
    Reviewed-by: Adam Klein <adamk@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Cr-Commit-Position: refs/heads/master@{#57261}

Refs: v8/v8@0483e9a

PR-URL: nodejs#24125
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
pull bot pushed a commit to shakir-abdo/node that referenced this pull request Dec 6, 2018
Original commit message:

    [api] Allow embedder to construct an Array from Local<Value>*

    Currently to obtain a v8::Array out of a C array or a std::vector,
    one needs to loop through the elements and call array->Set() multiple
    times, and these calls go into v8::Object::Set() which can be slow.
    This patch adds a new Array::New overload that converts a
    Local<Value>* with known size into a Local<Array>.

    Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188
    Reviewed-on: https://chromium-review.googlesource.com/c/1317049
    Reviewed-by: Yang Guo <yangguo@chromium.org>
    Reviewed-by: Adam Klein <adamk@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Cr-Commit-Position: refs/heads/master@{#57261}

Refs: v8/v8@0483e9a

PR-URL: nodejs#24125
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
@codebytere
Copy link
Member

@joyeecheung is this a candidate for v10.x? if so, could you please backport it?

refack pushed a commit to refack/node that referenced this pull request Jan 14, 2019
replace with C++ API.

Refs: nodejs#24125
PR-URL: nodejs#24614
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
refack pushed a commit to refack/node that referenced this pull request Jan 14, 2019
Original commit message:

    [api] Allow embedder to construct an Array from Local<Value>*

    Currently to obtain a v8::Array out of a C array or a std::vector,
    one needs to loop through the elements and call array->Set() multiple
    times, and these calls go into v8::Object::Set() which can be slow.
    This patch adds a new Array::New overload that converts a
    Local<Value>* with known size into a Local<Array>.

    Change-Id: I0a768f0e18eec51e78d58be455482ec6425ca188
    Reviewed-on: https://chromium-review.googlesource.com/c/1317049
    Reviewed-by: Yang Guo <yangguo@chromium.org>
    Reviewed-by: Adam Klein <adamk@chromium.org>
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Cr-Commit-Position: refs/heads/master@{#57261}

Refs: v8/v8@0483e9a

PR-URL: nodejs#24125
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lib / src Issues and PRs related to general changes in the lib or src directory.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants