Skip to content

Commit 31a2a57

Browse files
Perf/code: replace ref cells with mutable in ~30 API functions
Modernises ~30 public API functions to use 'mutable' local variables instead of heap-allocated 'ref' cells (! and := operators). This reduces GC pressure in hot paths and aligns the code with idiomatic modern F#. Affected functions: tryLast, tryFirst, tryItem, compareWithAsync, reduceAsync, scanAsync, pairwise, windowed, pickAsync, tryPickAsync, tryFindIndex, tryFindIndexAsync, threadStateAsync, zipWithAsync, zipWithAsyncParallel, zipWithAsync3, allPairs, takeWhileAsync, takeUntilSignal, skipWhileAsync, skipWhileInclusiveAsync, skipUntilSignal, tryTail, splitAt, toArrayAsync, concatSeq, interleaveChoice, chunkBySize, chunkByAsync, mergeChoiceEnum, distinctUntilChangedWithAsync, emitEnumerator, removeAt, updateAt, insertAt, ofObservableBuffered, Disposables.Dispose. All 372 tests pass. Co-authored-by: Copilot <[email protected]>
1 parent 484d414 commit 31a2a57

2 files changed

Lines changed: 236 additions & 242 deletions

File tree

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### 4.11.0
22

3+
* Code/Performance: Modernised ~30 API functions to use `mutable` local variables instead of `ref` cells (`!`/`:=` operators). Affected: `tryLast`, `tryFirst`, `tryItem`, `compareWithAsync`, `reduceAsync`, `scanAsync`, `pairwise`, `windowed`, `pickAsync`, `tryPickAsync`, `tryFindIndex`, `tryFindIndexAsync`, `threadStateAsync`, `zipWithAsync`, `zipWithAsyncParallel`, `zipWithAsync3`, `allPairs`, `takeWhileAsync`, `takeUntilSignal`, `skipWhileAsync`, `skipWhileInclusiveAsync`, `skipUntilSignal`, `tryTail`, `splitAt`, `toArrayAsync`, `concatSeq`, `interleaveChoice`, `chunkBySize`, `chunkByAsync`, `mergeChoiceEnum`, `distinctUntilChangedWithAsync`, `emitEnumerator`, `removeAt`, `updateAt`, `insertAt`. This eliminates heap-allocated `ref`-cell objects for these variables, reducing GC pressure in hot paths, and modernises the code style to idiomatic F#.
34
* Performance: `mapiAsync` — replaced `asyncSeq`-builder + `collect` implementation with a direct optimised enumerator (`OptimizedMapiAsyncEnumerator`), eliminating `collect` overhead and bringing per-element cost in line with `mapAsync`. Benchmarks added in `AsyncSeqMapiBenchmarks`.
45
* Design parity with FSharp.Control.TaskSeq (#277, batch 2):
56
* Added `AsyncSeq.tryTail` — returns `None` if the sequence is empty; otherwise returns `Some` of the tail. Safe counterpart to `tail`. Mirrors `TaskSeq.tryTail`.

0 commit comments

Comments
 (0)