Skip to content

Capture-by-reference for class-member var captures costs +22-24% on the shapes it fixes (#10485 follow-up) #10616

Description

@proggeramlug

Follow-up to #10485/#10489, fixed in PR #10615. Filing for tracking only — the fix is correct and should ship.

Measurement (from PR #10615, perf stat -e instructions, 3 runs each)

workload instructions
constructor writes to a function-nested class's captured var +22.3%
static-method writes to the same shape +24.8%
closure-heavy, no capture (control) −0.04% (noise)
compile-time steady state (control) +0.05% (noise)

The controls matter: the cost is confined to the shape the fix repairs, not spread across closures generally.

Why there is no valid "before" number

The baseline was faster because it silently skipped the write-back this fix performs — a var captured by a
class member fell back to a stale value-snapshot, so constructor and static-method writes were dropped entirely.
Measuring "the regression" against code that didn't do the work is measuring nothing.

This is the fourth instance of one pattern

Four correctness fixes in the package-audit campaign have landed with an instruction cost whose baseline was
invalid for the same reason — the old path was cheap because it was wrong:

Worth asking whether they share a cause: each replaces a wrong-but-cheap fast path with a correct path that
re-derives or re-resolves something per operation. If so, the same class of fix — resolve once and cache at the
call site, rather than per operation — may address several at once. #10414 is the precedent: Array.prototype.push
re-derived its receiver 6x per call, and fixing that was worth −74.6%.

Activity

  1. added
    performanceRuntime, compile-time, build-size, or memory performance
    package-auditFound by the 2026 package audit: compiling real npm packages from source instead of native bindings
    on Sep 18, 2026
  2. proggeramlug commented on Oct 4, 2026

    @proggeramlug
    ContributorAuthor

    Progress in #11940 (fresh-class evaluations), instructions per op: static method 5360 → 505, freshnew 9201 → 5846, ctor 13288 → 10686, evalnew 38121 → 27664; tsc −0.39% (fulls 76 = 76). Leaving open.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    package-auditFound by the 2026 package audit: compiling real npm packages from source instead of native bindingsperformanceRuntime, compile-time, build-size, or memory performance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions