Skip to content

Conversation

@mcollina
Copy link
Member

This reverts commit d8f535b.

As part of #37937, I tracked down a regression introduced by #36767.

With optional chaining:

Screenshot 2021-04-15 at 12 07 40

Without optional chanining:

Screenshot 2021-04-15 at 12 07 51

This sits in the hot path for HTTP.


I will recommend caution in adopting optional chaining in other areas of the Node.js.

@nodejs-github-botnodejs-github-bot added needs-ci PRs that need a full CI run. timers Issues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout. labels Apr 15, 2021
@mcollinamcollina requested a review from ronagApril 15, 2021 10:15
@Flarna
Copy link
Member

Should we report this towards v8?

@ronag
Copy link
Member

Yea this seems like a V8 issue. @nodejs/v8

Copy link
Member

@ronagronag left a comment

Choose a reason for hiding this comment

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

LGTM, gj

@nodejs-github-bot
Copy link
Collaborator

@mcollina
Copy link
MemberAuthor

cc @nodejs/tsc

@targos
Copy link
Member

I wanted to prove it with a benchmark and open a V8 issue but it seems optional chaining is mostly faster (at least with V8 8.9): https://jsben.ch/BwkJK

@ronag
Copy link
Member

ronag commented Apr 15, 2021

This reverts commit d8f535b.

As part of #37937, I tracked down a regression introduced by #36767.

With optional chaining:

Screenshot 2021-04-15 at 12 07 40

Without optional chanining:

Screenshot 2021-04-15 at 12 07 51

This sits in the hot path for HTTP.

I will recommend caution in adopting optional chaining in other areas of the Node.js.

@mcollina: What node version were you trying this on?

@mcollina
Copy link
MemberAuthor

I wanted to prove it with a benchmark and open a V8 issue but it seems optional chaining is mostly faster (at least with V8 8.9): https://jsben.ch/BwkJK

I have literally no clue why, but without optional chaining those function calls get inlined.

Those flamegraphs come from master.

@targos
Copy link
Member

those function calls get inlined.

That's a good point, thanks. I'll try to do a different benchmark to show that optional chaining prevents inlining.

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@targos
Copy link
Member

those function calls get inlined.

That's a good point, thanks. I'll try to do a different benchmark to show that optional chaining prevents inlining.

It's not that easy. Everything gets inlined with this example:

'use strict';functiongetPropClassic(obj){returnobj&&obj.prop;}functiongetPropOptional(obj){returnobj?.prop;}constobj={prop: 42};functiontestGetPropClassic(obj){returngetPropClassic(obj);}functiontestGetPropOptional(obj){returngetPropOptional(obj);}for(leti=0;i<1e6;i++){testGetPropClassic(obj);testGetPropOptional(obj);}
> node --trace-turbo-inlining bench.js Considering 000002D5A0AE59D8{0x004b3832c8e1 <SharedFunctionInfo testGetPropClassic>} for inlining with 000002D5A0AE59E8{0x004b3832d821 <FeedbackVector[2]>} Inlining small function(s) at call site #45:JSCall Inlining 000002D5A0AE59D8{0x004b3832c8e1 <SharedFunctionInfo testGetPropClassic>} into 000002D5A0AE4A98{0x004b3832c779 <SharedFunctionInfo>} Considering 000002D5A0AE63A8{0x004b3832c841 <SharedFunctionInfo getPropClassic>} for inlining with 000002D5A0AE63B8{0x004b3832d7e1 <FeedbackVector[2]>} Inlining small function(s) at call site #80:JSCall Inlining 000002D5A0AE63A8{0x004b3832c841 <SharedFunctionInfo getPropClassic>} into 000002D5A0AE4A98{0x004b3832c779 <SharedFunctionInfo>} Considering 000002D5A0AE69E8{0x004b3832c931 <SharedFunctionInfo testGetPropOptional>} for inlining with 000002D5A0AE6DF8{0x004b3832d861 <FeedbackVector[2]>} Inlining small function(s) at call site #50:JSCall Inlining 000002D5A0AE69E8{0x004b3832c931 <SharedFunctionInfo testGetPropOptional>} into 000002D5A0AE4A98{0x004b3832c779 <SharedFunctionInfo>} Considering 000002D5A0AE78A8{0x004b3832c891 <SharedFunctionInfo getPropOptional>} for inlining with 000002D5A0AE78B8{0x004b3832d7a1 <FeedbackVector[2]>} Inlining small function(s) at call site #129:JSCall Inlining 000002D5A0AE78A8{0x004b3832c891 <SharedFunctionInfo getPropOptional>} into 000002D5A0AE4A98{0x004b3832c779 <SharedFunctionInfo>} 

@jasnell
Copy link
Member

@targos I'm curious... Can you try that example but with obj replaced with a class with a getter?

classObj{getprop(){return42;}}constobj=newObj()

Also, let's see what happens when you alternate calls between the argument being obj and undefined.

Copy link
Member

@mhdawsonmhdawson left a comment

Choose a reason for hiding this comment

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

LGTM

@nodejs-github-bot
Copy link
Collaborator

nodejs-github-bot commented Apr 19, 2021

@mcollina
Copy link
MemberAuthor

"Build from tarball / test-tarball-linux (pull_request) " keeps failing. Is that required to pass for this landing? cc @BethGriggs

@BethGriggs
Copy link
Member

Failure is js-native-api/test_object/test, which was mentioned as being fixed by #38000. Rerunning as that has just landed 🤞🏻

@BethGriggs
Copy link
Member

I hadn't appreciated before that GH actions do not rebase. fc20e83 was the fix for the failure seen here (js-native-api/test_object/test). I think we should go ahead and land rather than rebase and rerun (due to the timing).

BethGriggs pushed a commit that referenced this pull request Apr 19, 2021
This reverts commit d8f535b. PR-URL: #38245 Reviewed-By: Gerhard Stöbich <[email protected]> Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Zijian Liu <[email protected]> Reviewed-By: Beth Griggs <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Rich Trott <[email protected]>
@BethGriggs
Copy link
Member

Landed in a0261d2

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ciPRs that need a full CI run.timersIssues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

15 participants

@mcollina@Flarna@ronag@nodejs-github-bot@targos@jasnell@BethGriggs@Trott@lpinca@cjihrig@richardlau@mhdawson@Lxxyx@aduh95@VoltrexKeyva