Skip to content
Draft
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions release-notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Release notes:

1.0.0
- adds taskSeqDynamic computation expression and TaskSeqDynamic/TaskSeqDynamicInfo types for dynamic (FSI-compatible) resumable code, fixing issue where taskSeq would raise NotImplementedException in F# Interactive, #246
- perf: toResizeArrayAsync (and therefore toArrayAsync, toListAsync, toResizeArrayAsync, toIListAsync) uses a direct loop instead of going through iter, avoiding a lambda and DU allocation per call
- perf: tryItem uses a simpler loop that skips the redundant inner index check on every iteration
- perf: TaskSeq.chunkBy and chunkByAsync reuse the ResizeArray buffer between chunks, reducing allocations on sequences with many chunk boundaries
- fixes: TaskSeq.insertAt, insertManyAt, removeAt, removeManyAt, updateAt now raise ArgumentNullException (not NullReferenceException) when given a null source; insertManyAt also validates the values argument
- refactor: simplify lengthBy and lengthBeforeMax to use while! and remove the redundant mutable 'go' and initial MoveNextAsync
Expand Down
26 changes: 15 additions & 11 deletions src/FSharp.Control.TaskSeq/TaskSeqInternal.fs
Original file line number Diff line number Diff line change
Expand Up @@ -532,12 +532,16 @@ module internal TaskSeqInternal =
yield result
}

let toResizeArrayAsync source =
let toResizeArrayAsync (source: TaskSeq<'T>) =
checkNonNull (nameof source) source

task {
let res = ResizeArray()
do! source |> iter (SimpleAction(fun item -> res.Add item))
let res = ResizeArray<'T>()
use e = source.GetAsyncEnumerator CancellationToken.None

while! e.MoveNextAsync() do
res.Add e.Current

return res
}

Expand Down Expand Up @@ -915,14 +919,14 @@ module internal TaskSeqInternal =
let! step = e.MoveNextAsync()
go <- step

while go && idx <= index do
if idx = index then
foundItem <- Some e.Current
go <- false
else
let! step = e.MoveNextAsync()
go <- step
idx <- idx + 1
// advance past the first `index` elements, then capture the current element
while go && idx < index do
let! step = e.MoveNextAsync()
go <- step
idx <- idx + 1

if go then
foundItem <- Some e.Current

return foundItem
}
Expand Down