Skip to content

Commit f42f94b

Browse files
authored
Merge pull request fsprojects#198 from fsprojects/daily-perf-improver/fix-recursive-on2-patterns
Daily Perf Improver: Optimize mapAsync for significant performance gains
2 parents 6f5a37c + 716670f commit f42f94b

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

src/FSharp.Control.AsyncSeq/AsyncSeq.fs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -795,14 +795,32 @@ module AsyncSeq =
795795
// --------------------------------------------------------------------------
796796
// Additional combinators (implemented as async/asyncSeq computations)
797797

798+
// Optimized mapAsync enumerator that avoids computation builder overhead
799+
type private OptimizedMapAsyncEnumerator<'T, 'TResult>(source: IAsyncEnumerator<'T>, f: 'T -> Async<'TResult>) =
800+
let mutable disposed = false
801+
802+
interface IAsyncEnumerator<'TResult> with
803+
member _.MoveNext() = async {
804+
let! moveResult = source.MoveNext()
805+
match moveResult with
806+
| None -> return None
807+
| Some value ->
808+
let! mapped = f value
809+
return Some mapped
810+
}
811+
812+
member _.Dispose() =
813+
if not disposed then
814+
disposed <- true
815+
source.Dispose()
816+
798817
let mapAsync f (source : AsyncSeq<'T>) : AsyncSeq<'TResult> =
799818
match source with
800819
| :? AsyncSeqOp<'T> as source -> source.MapAsync f
801820
| _ ->
802-
asyncSeq {
803-
for itm in source do
804-
let! v = f itm
805-
yield v }
821+
{ new IAsyncEnumerable<'TResult> with
822+
member _.GetEnumerator() =
823+
new OptimizedMapAsyncEnumerator<'T, 'TResult>(source.GetEnumerator(), f) :> IAsyncEnumerator<'TResult> }
806824

807825
let mapiAsync f (source : AsyncSeq<'T>) : AsyncSeq<'TResult> = asyncSeq {
808826
let i = ref 0L

0 commit comments

Comments
 (0)