Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions src/FSharp.Control.AsyncSeq/AsyncSeq.fs
Original file line number Diff line number Diff line change
Expand Up @@ -795,14 +795,32 @@ module AsyncSeq =
// --------------------------------------------------------------------------
// Additional combinators (implemented as async/asyncSeq computations)

// Optimized mapAsync enumerator that avoids computation builder overhead
type private OptimizedMapAsyncEnumerator<'T, 'TResult>(source: IAsyncEnumerator<'T>, f: 'T -> Async<'TResult>) =
let mutable disposed = false

interface IAsyncEnumerator<'TResult> with
member _.MoveNext() = async {
let! moveResult = source.MoveNext()
match moveResult with
| None -> return None
| Some value ->
let! mapped = f value
return Some mapped
}

member _.Dispose() =
if not disposed then
disposed <- true
source.Dispose()

let mapAsync f (source : AsyncSeq<'T>) : AsyncSeq<'TResult> =
match source with
| :? AsyncSeqOp<'T> as source -> source.MapAsync f
| _ ->
asyncSeq {
for itm in source do
let! v = f itm
yield v }
{ new IAsyncEnumerable<'TResult> with
member _.GetEnumerator() =
new OptimizedMapAsyncEnumerator<'T, 'TResult>(source.GetEnumerator(), f) :> IAsyncEnumerator<'TResult> }

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