Repository navigation
Performance regression in v12 caused by primordials #29766
Description
Activity
- addedperformanceIssues and PRs related to the performance of Node.js.Issues and PRs related to the performance of Node.js.
on Sep 29, 2019 - addedv8 engineIssues and PRs related to the V8 dependency.Issues and PRs related to the V8 dependency.
on Sep 30, 2019 From my tests, it seems to be related to inlining.
I just noticed that things like
primordials.Reflectare not frozen, but instead the slowdown probably comes fromObject.create(null)which turns the objects into dictionary mode.Can we have V8 migrate everything captured in the snapshot to fast properties?
And if all else fails...
try { eval('%ToFastProperties(primordials.Reflect)') } catch {}:)cc @nodejs/v8
For reference the primordials are baked in https://github.com/nodejs/node/blob/6ce87c0/lib/internal/per_context/primordials.js
One idea about the way forward: put the primordials beind a configure-time flag, and figure out how to fix the performance regression before turning it back on.
@nodejs/process ^ any opinions on the idea in #29766 (comment) ?
How much would we gain by not freezing the objects, for now? That could be put behind a flag pretty easily, right?
@addaleax I think we need to identify a suitable benchmark to compare the impact of removing certain bits in the
primorials.js...any suggestions? (from the tweet I think @mcollina @MylesBorins @bmeck have experience on this)I just did it manually, building two node versions and run some of our microbenchmarks.
The way how I fixed it is by just doing a simple assignment / destructuring:
Line 24 in ed5eaa0
const { Math, Object, Reflect } = primordials; I would just do that everywhere, and we would be good I think.
@mcollina Thanks, that would probably be good for a code & learn task or a beginner task. I'll see if I can get this done through nodejs/code-and-learn#97 and if not, I'll spin off a separate issue about this specific task.
- added a commit that references this issue
on Nov 3, 2019 19 remaining items
- added 2 commits that reference this issue
on Dec 1, 2019 - added 2 commits that reference this issue
on Dec 17, 2019 - added 2 commits that reference this issue
on Jan 13, 2020 - added 2 commits that reference this issue
on Feb 6, 2020 Both upstream issues has been closed as fixed. Should we keep this open?
Closing. please reopen if things are not fixed
I have heard about performance regressions caused by transition to primordials in v12, but couldn't find a tracking issue for the regression, so opening this to make sure we are tracking it and can work with the upstream to get this handled, on way or another (feel free to close this if there is already an issue opened here).
The regressions seem to come from two types of code patterns:
Function.prototype.{call, apply}instead of just calling them directly. There is an issue opened in the upstream by @bmeckhttps://bugs.chromium.org/p/v8/issues/detail?id=9702
primordialsnamespace are frozen so lookups likeconst { Reflect } = primordials; Reflect.apply(...);is slower than justReflect.applywhenReflectcomes from the global object. This can be mitigated by caching the lookup results upfront, e.g. event: improve performance of EventEmitter.emit #29633 by @mcollina There is also a fairly odd tracking issue for this in the upstream: https://bugs.chromium.org/p/v8/issues/detail?id=6831cc @MylesBorins (https://twitter.com/MylesBorins/status/1173390304742785024)