@@ -734,23 +734,64 @@ module AsyncSeq =
734734 dispose e
735735 | _ -> () } }
736736
737+ // Optimized iterAsync implementation to reduce allocations
738+ type internal OptimizedIterAsyncEnumerator < 'T >( enumerator : IAsyncEnumerator < 'T >, f : 'T -> Async < unit >) =
739+ let mutable disposed = false
740+
741+ member _.IterateAsync () =
742+ let rec loop () = async {
743+ let! next = enumerator.MoveNext()
744+ match next with
745+ | Some value ->
746+ do ! f value
747+ return ! loop()
748+ | None -> return ()
749+ }
750+ loop()
751+
752+ interface IDisposable with
753+ member _.Dispose () =
754+ if not disposed then
755+ disposed <- true
756+ enumerator.Dispose()
757+
758+ // Optimized iteriAsync implementation with direct tail recursion
759+ type internal OptimizedIteriAsyncEnumerator < 'T >( enumerator : IAsyncEnumerator < 'T >, f : int -> 'T -> Async < unit >) =
760+ let mutable disposed = false
761+
762+ member _.IterateAsync () =
763+ let rec loop count = async {
764+ let! next = enumerator.MoveNext()
765+ match next with
766+ | Some value ->
767+ do ! f count value
768+ return ! loop ( count + 1 )
769+ | None -> return ()
770+ }
771+ loop 0
772+
773+ interface IDisposable with
774+ member _.Dispose () =
775+ if not disposed then
776+ disposed <- true
777+ enumerator.Dispose()
778+
737779 let iteriAsync f ( source : AsyncSeq < _ >) =
738780 async {
739- use ie = source.GetEnumerator()
740- let count = ref 0
741- let! move = ie.MoveNext()
742- let b = ref move
743- while b.Value.IsSome do
744- do ! f ! count b.Value.Value
745- let! moven = ie.MoveNext()
746- do incr count
747- b := moven
781+ let enum = source.GetEnumerator()
782+ use optimizer = new OptimizedIteriAsyncEnumerator<_>( enum , f)
783+ return ! optimizer.IterateAsync()
748784 }
749785
750786 let iterAsync ( f : 'T -> Async < unit >) ( source : AsyncSeq < 'T >) =
751787 match source with
752788 | :? AsyncSeqOp< 'T> as source -> source.IterAsync f
753- | _ -> iteriAsync ( fun i x -> f x) source
789+ | _ ->
790+ async {
791+ let enum = source.GetEnumerator()
792+ use optimizer = new OptimizedIterAsyncEnumerator<_>( enum , f)
793+ return ! optimizer.IterateAsync()
794+ }
754795
755796 let iteri ( f : int -> 'T -> unit ) ( inp : AsyncSeq < 'T >) = iteriAsync ( fun i x -> async.Return ( f i x)) inp
756797
0 commit comments