Skip to content

Perf: typed array element access (eliminate per-site isinst ladder + boxing) #860

Description

@nickna

Part of #856 (perf epic). Depends on #856-F4 (typed locals). Drives the count-primes (28×) and array-methods (23×) gaps.

Summary

In compiled mode, every array element get/set emits a multi-way isinst type-dispatch ladder inline at the call site, plus index-boxing and element box/unbox — even when the array's element type is statically known (boolean[], number[]). The element store is backed by List<object>, so primitives are boxed.

Evidence (emitted IL)

isPrime[j] = false expands inline to:

isinst List`1<bool>      → if yes: SetArrayElementBool
else isinst $Array       → $Array::Set(int64, object)        (index + value boxed)
else isinst List`1<object> + _frozenObjects CWT probe → SetArrayElement
else isinst $Undefined / null → throw TypeError("Cannot set properties of ...")
else SetIndex(object,object,object)

This ladder is duplicated at every element site. countPrimes compiles to 1196 bytes of IL for a sieve. Reads mirror it (isinst List<bool>get_Itembox BooleanIsTruthy).

Bonus O(n) trap: the push-normalize path's IList fallback (countPrimes IL_0086, arrayMethods IL_0074) copies the entire list element-by-element into a new List<object>. Harmless when the array is already List<object> (it short-circuits), but a latent O(n)-per-call hazard if that branch is ever reached in a loop.

Recommended fix

Once #856-F4 gives a concretely-typed array local (List<bool> / List<double> or bool[]/double[]):

  • emit direct get_Item / set_Item for monomorphic typed arrays, skipping the isinst ladder and the box/unbox;
  • keep the ladder only as the fallback for genuinely object-typed / polymorphic arrays.

Investigate

  • Where the index get/set ladder is emitted (RuntimeEmitter.Objects.Index.cs, ILEmitter index-assignment sites) and how to gate a typed fast path on F4's static-type info.
  • Whether $Array vs List<object> representation can be unified for the typed case, or whether a List<double>/bool[] backing store needs interop shims for $Array consumers.

Acceptance

  • Monomorphic number[]/boolean[] index ops emit a direct typed accessor, no isinst ladder, no per-element box.
  • No regression in dotnet test, Test262, TS conformance.

Scope / priority

High value, medium risk. Sequence after F4.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceRuntime/codegen performance work

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions