Skip to content

Commit 8366ae5

Browse files
authored
Merge branch 'main' into daily-perf-improver/fix-append-memory-leak
2 parents 6626a1c + 9c20d3f commit 8366ae5

4 files changed

Lines changed: 79 additions & 1 deletion

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: 'Daily Perf Improver Build Steps'
2+
description: 'Sets up the environment and builds FSharp.Control.AsyncSeq for performance testing and development'
3+
runs:
4+
using: 'composite'
5+
steps:
6+
- name: Setup .NET SDK
7+
uses: actions/setup-dotnet@v3
8+
with:
9+
dotnet-version: '8.0.x'
10+
dotnet-quality: 'ga'
11+
12+
- name: Restore dependencies
13+
shell: bash
14+
run: dotnet restore
15+
16+
- name: Build solution in Release mode
17+
shell: bash
18+
run: dotnet build -c Release --no-restore
19+
20+
- name: Run tests to verify build
21+
shell: bash
22+
run: dotnet test -c Release --no-build --logger trx --results-directory TestResults/
23+
24+
- name: Run performance baseline test
25+
shell: bash
26+
run: dotnet fsi tests/FSharp.Control.AsyncSeq.Tests/AsyncSeqPerf.fsx
27+
28+
- name: Setup tools for performance analysis
29+
shell: bash
30+
run: |
31+
# Install dotnet tools for performance analysis (if needed)
32+
echo "Build environment ready for performance testing"
33+
echo "Available tools:"
34+
echo "- dotnet build/test for regular builds"
35+
echo "- dotnet fsi for F# Interactive and performance scripts"
36+
echo "- Release builds available in src/FSharp.Control.AsyncSeq/bin/Release/"
37+
echo "- Test results in TestResults/"
38+
39+
- name: Display environment info
40+
shell: bash
41+
run: |
42+
echo "=== Environment Information ==="
43+
echo "Operating System: $(uname -a)"
44+
echo ".NET Version: $(dotnet --version)"
45+
echo "F# Compiler: $(dotnet fsc --version 2>/dev/null || echo 'F# Compiler available via dotnet')"
46+
echo "Working Directory: $(pwd)"
47+
echo "Available cores: $(nproc)"
48+
echo "Memory: $(free -h | head -n 2)"
49+
echo "=== Build Artifacts ==="
50+
find src/FSharp.Control.AsyncSeq/bin/Release -type f -name "*.dll" 2>/dev/null || echo "No build artifacts found"

src/FSharp.Control.AsyncSeq/AsyncSeq.fs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,11 @@ module AsyncSeq =
14191419
let interleave (source1:AsyncSeq<'T>) (source2:AsyncSeq<'T>) : AsyncSeq<'T> =
14201420
interleaveChoice source1 source2 |> map (function Choice1Of2 x -> x | Choice2Of2 x -> x)
14211421

1422+
let interleaveMany (xs : #seq<AsyncSeq<'T>>) : AsyncSeq<'T> =
1423+
let mutable result = empty
1424+
for x in xs do
1425+
result <- interleave result x
1426+
result
14221427

14231428
let bufferByCount (bufferSize:int) (source:AsyncSeq<'T>) : AsyncSeq<'T[]> =
14241429
if (bufferSize < 1) then invalidArg "bufferSize" "must be positive"

src/FSharp.Control.AsyncSeq/AsyncSeq.fsi

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,11 +462,15 @@ module AsyncSeq =
462462
/// large or infinite sequences.
463463
val sortByDescending : projection:('T -> 'Key) -> source:AsyncSeq<'T> -> array<'T> when 'Key : comparison
464464
#endif
465-
465+
466466
/// Interleaves two async sequences of the same type into a resulting sequence. The provided
467467
/// sequences are consumed in lock-step.
468468
val interleave : source1:AsyncSeq<'T> -> source2:AsyncSeq<'T> -> AsyncSeq<'T>
469469

470+
/// Interleaves a sequence of async sequences into a resulting async sequence. The provided
471+
/// sequences are consumed in lock-step.
472+
val interleaveMany : source:#seq<AsyncSeq<'T>> -> AsyncSeq<'T>
473+
470474
/// Interleaves two async sequences into a resulting sequence. The provided
471475
/// sequences are consumed in lock-step.
472476
val interleaveChoice : source1:AsyncSeq<'T1> -> source2:AsyncSeq<'T2> -> AsyncSeq<Choice<'T1,'T2>>

tests/FSharp.Control.AsyncSeq.Tests/AsyncSeqTests.fs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,25 @@ let ``AsyncSeq.interleave first empty``() =
406406
let merged = AsyncSeq.interleave s1 s2 |> AsyncSeq.toListSynchronously
407407
Assert.True([1 ; 2 ; 3] = merged)
408408

409+
[<Test>]
410+
let ``AsyncSeq.interleaveMany empty``() =
411+
let merged = AsyncSeq.interleaveMany [] |> AsyncSeq.toListSynchronously
412+
Assert.True(List.isEmpty merged)
413+
414+
[<Test>]
415+
let ``AsyncSeq.interleaveMany 1``() =
416+
let s1 = AsyncSeq.ofSeq ["a";"b";"c"]
417+
let merged = AsyncSeq.interleaveMany [s1] |> AsyncSeq.toListSynchronously
418+
Assert.True(["a" ; "b" ; "c" ] = merged)
419+
420+
[<Test>]
421+
let ``AsyncSeq.interleaveMany 3``() =
422+
let s1 = AsyncSeq.ofSeq ["a";"b"]
423+
let s2 = AsyncSeq.ofSeq ["i";"j";"k";"l"]
424+
let s3 = AsyncSeq.ofSeq ["x";"y";"z"]
425+
let merged = AsyncSeq.interleaveMany [s1;s2;s3] |> AsyncSeq.toListSynchronously
426+
Assert.True(["a"; "x"; "i"; "y"; "b"; "z"; "j"; "k"; "l"] = merged)
427+
409428

410429
[<Test>]
411430
let ``AsyncSeq.bufferByCount``() =

0 commit comments

Comments
 (0)