Skip to content

perf: object representation is now the binding constraint on the retain cluster (72 bytes per 2-field literal; 216 MB written to store 48 MB) #7916

Description

@proggeramlug

Summary

Established while decomposing the retain cluster's GC cost (gc-handoff/RETAIN4-NOTES.md): the collector is no longer the binding constraint on these benchmarks — object representation is.

A 2-field object literal costs 72 bytes. retain writes 216 MB to store 48 MB of numbers — a 4.5x write amplification.

The decisive evidence is that the remaining gap survives a hypothetically free collector:

program wall GC pause pause frac scriptc
retain 159.5 ms 52.0 33% 109
retain1 71.4 38.7 54% 38
retain_wide 206.2 75.4 37% 122
retain_wide1 73.9 32.3 44% 43
shapes 64.8 4.6 7% 38

retain_wide (206.2 − 75.4 = 130.8 ms of pure mutator) and shapes (60.2 ms of mutator) still lose to scriptc with a zero-cost collector. retain would need exactly zero GC to reach parity. So further collector work cannot close this cluster.

Why this is the representation problem, not a GC problem

scriptc's advantage here is not its refcounting — it is that it stores these objects more compactly. 72 bytes for two fields means header + slot overhead dominates payload. The write amplification is then paid twice: once in allocation bandwidth, and again in everything downstream that must touch those bytes (promotion, copying, cache pressure).

This is the concrete, measured instance of the direction recorded in the representation-selection RFC: type-driven representation selection rather than uniform NaN-boxed slots for every field.

Corollaries

  • shapes should leave the "high-survival GC" cluster. At 7% GC pause it is a mutator benchmark that was mis-grouped; GC levers will not move it.
  • Parallel GC is not indicated for this cluster (independently confirmed): the per-object visits split roughly 50/50 into work already deleted by perf(gc): describe a promoted block's page-object list instead of storing it #7914 and ~9.6 ms of a 159 ms program. There is not enough collector time left to parallelise, which matches the standing directive that parallelism is a last resort.

Acceptance

  • A measured proposal for compacting at least the common shapes here (small fixed-field object literals with numeric fields).
  • Report bytes-per-object and total write volume alongside any speedup — those are the primary metrics for this issue, not wall clock.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceRuntime, 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