Skip to content

perf(ParseResults.getAllResults): Drop Seq pipeline for direct buffer#319

Open
dimension-zero wants to merge 1 commit into
fsprojects:masterfrom
dimension-zero:pr/31-allocation-audit
Open

perf(ParseResults.getAllResults): Drop Seq pipeline for direct buffer#319
dimension-zero wants to merge 1 commit into
fsprojects:masterfrom
dimension-zero:pr/31-allocation-audit

Conversation

@dimension-zero
Copy link
Copy Markdown
Contributor

perf(ParseResults.getAllResults): Drop Seq pipeline for direct buffer

The previous implementation chained
Seq.concat -> Seq.filter -> Seq.sortBy -> Seq.map -> Seq.toList,
allocating an enumerator + closure per stage. Replace with a single
ResizeArray fill, one System.Array.Sort using the same source-priority
key, and a typed projection into a final list. Two arrays total instead
of five-ish Seq wrappers.

  • Behaviour preserved byte-identical: same filter predicate, same
    sort key (((int Source) <<< 16) + Index), same final shape ('Template
    list).
  • Hot path: this is called by GetAllResults, ToString, Equals,
    GetHashCode (via CachedAllResults), and IComparable.CompareTo. Each
    hit saves ~4 wrapper allocations.
  • All 112 tests pass unchanged.

A proper benchmark belongs in benchmarks/Argu.Benchmarks (added by
pr/25-benchmark-harness); allocation deltas will be measured there
once both branches merge to master.


The previous implementation chained
  Seq.concat -> Seq.filter -> Seq.sortBy -> Seq.map -> Seq.toList,
allocating an enumerator + closure per stage. Replace with a single
ResizeArray fill, one System.Array.Sort using the same source-priority
key, and a typed projection into a final list. Two arrays total instead
of five-ish Seq wrappers.

* Behaviour preserved byte-identical: same filter predicate, same
  sort key (((int Source) <<< 16) + Index), same final shape ('Template
  list).
* Hot path: this is called by GetAllResults, ToString, Equals,
  GetHashCode (via CachedAllResults), and IComparable.CompareTo. Each
  hit saves ~4 wrapper allocations.
* All 112 tests pass unchanged.

A proper benchmark belongs in benchmarks/Argu.Benchmarks (added by
pr/25-benchmark-harness); allocation deltas will be measured there
once both branches merge to master.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant