You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Decomposed churn on the quiet mini (best-of-3), Perry vs node:
variant
Perry
node
ratio
churn (full)
2.72 s
0.17 s
16.0×
churn_alloc — object literal + push
2.44 s
0.14 s
17.4×
push_cls — new Node(v,w) + push
3.99 s
0.14 s
28.5×
push_num — numbers into array
0.30 s
0.11 s
2.7×
churn_read — element reads only
0.35 s
0.08 s
4.3×
A declared class is 63% slower to construct than an equivalent object literal.
That ordering is backwards and is the reason this is filed as a defect rather
than a missing optimization. new Node(v, w) on a fixed-shape declared class
is the most statically-known construction form in the language: the field set,
their order, the class id and the shape are all known at compile time. The
object literal has to mint an anon shape (__AnonShape_…) and still wins.
Whatever the declared-class path is doing extra, it is doing it in spite of
having strictly more static information — so the likely finding is a fast path
that the literal reaches and the class does not, or per-construction work that
the class path repeats and the literal amortizes.
Where to look first
perf(codegen): elide provably-dead per-store bookkeeping on class-field stores #7486's elision may not reach declared classes. It elides dead
default-undefined field inits when the ctor opens with a run of this.f = <param> statements, proven by ctor_prologue_param_assigned_fields
(lower_call/field_init.rs). It was measured on the synthesized anon-shape
ctor. A user-declared class Node { constructor(v, w) { this.v = v; this.w = w } }
should qualify — verify it actually does, and if it does not, why.
js_gc_init_typed_shape_layout (7.7% of churn_alloc) — is it emitted
per construction on the class path but hoisted/absent on the literal path?
Typed-feedback guards (9.2%) — does the class path instrument sites the
literal path does not?
Method
Compile both shapes with --trace llvm and diff the per-construction call
census (that is how #7501's admission analysis was verified). The difference
should be visible as concrete calls, not inferred from timings — and it is
cheap to get, which is why this may be a quick bisect rather than a project.
Provenance
Measured on the pinned quiet host, symbolicated with PERRY_DEBUG_SYMBOLS=1,
1500 leaf samples. Part of the #7469 mutator-cost campaign; sibling findings
are the layout side-table cost (commented on #5094) and write-barrier cost.
Symptom
Decomposed
churnon the quiet mini (best-of-3), Perry vs node:churn(full)churn_alloc— object literal + pushpush_cls—new Node(v,w)+ pushpush_num— numbers into arraychurn_read— element reads onlyA declared class is 63% slower to construct than an equivalent object literal.
That ordering is backwards and is the reason this is filed as a defect rather
than a missing optimization.
new Node(v, w)on a fixed-shape declared classis the most statically-known construction form in the language: the field set,
their order, the class id and the shape are all known at compile time. The
object literal has to mint an anon shape (
__AnonShape_…) and still wins.Whatever the declared-class path is doing extra, it is doing it in spite of
having strictly more static information — so the likely finding is a fast path
that the literal reaches and the class does not, or per-construction work that
the class path repeats and the literal amortizes.
Where to look first
default-
undefinedfield inits when the ctor opens with a run ofthis.f = <param>statements, proven byctor_prologue_param_assigned_fields(
lower_call/field_init.rs). It was measured on the synthesized anon-shapector. A user-declared
class Node { constructor(v, w) { this.v = v; this.w = w } }should qualify — verify it actually does, and if it does not, why.
js_gc_init_typed_shape_layout(7.7% ofchurn_alloc) — is it emittedper construction on the class path but hoisted/absent on the literal path?
literal path does not?
Method
Compile both shapes with
--trace llvmand diff the per-construction callcensus (that is how #7501's admission analysis was verified). The difference
should be visible as concrete calls, not inferred from timings — and it is
cheap to get, which is why this may be a quick bisect rather than a project.
Provenance
Measured on the pinned quiet host, symbolicated with
PERRY_DEBUG_SYMBOLS=1,1500 leaf samples. Part of the #7469 mutator-cost campaign; sibling findings
are the layout side-table cost (commented on #5094) and write-barrier cost.