@@ -25,21 +25,29 @@ type SigStreamBuilder() =
2525 | ValueNone -> StateController( ValueNone), StateController( ValueNone)
2626 | ValueSome ( ms, fs) -> ms, fs
2727 let mvs , ms = m ms ctx
28- let results = ResizeArray()
29- let mutable currentFs = fs
30- for mv in mvs do
31- let fStream = f mv
32- let fvs , newFs = fStream currentFs ctx
33- for fv in fvs do results.Add( fv)
34- currentFs <- newFs
35- do s.Set( ms, currentFs)
36- results :> seq<_>, s
28+ // Fast path: most streams emit exactly one value via [| x |], so skip ResizeArray
29+ match mvs with
30+ | :? ( 'a array) as arr when arr.Length = 1 ->
31+ let fStream = f arr[ 0 ]
32+ let fvs , newFs = fStream fs ctx
33+ do s.Set( ms, newFs)
34+ fvs, s
35+ | _ ->
36+ let results = ResizeArray()
37+ let mutable currentFs = fs
38+ for mv in mvs do
39+ let fStream = f mv
40+ let fvs , newFs = fStream currentFs ctx
41+ for fv in fvs do results.Add( fv)
42+ currentFs <- newFs
43+ do s.Set( ms, currentFs)
44+ results :> seq<_>, s
3745
3846 member inline _.Return ( x ) : SigStream < _ , _ , unit > =
39- fun s _ -> Seq.singleton x , s
47+ fun s _ -> [| x |] :> seq <_> , s
4048
4149 member inline _.Yield ( x ) : SigStream < _ , _ , unit > =
42- fun s _ -> Seq.singleton x , s
50+ fun s _ -> [| x |] :> seq <_> , s
4351
4452 member inline _.ReturnFrom ( v ) = v
4553
@@ -71,7 +79,8 @@ let ofSeq (sequence: seq<_>) : SigStream<_,_,_> =
7179 | ValueSome e -> e
7280 match enumerator.MoveNext() with
7381 | true ->
74- Seq.singleton enumerator.Current, s
82+ s.Set( enumerator)
83+ [| enumerator.Current |] :> seq<_>, s
7584 | false ->
7685 // failwith "Sequence contains no more elements"
7786 Seq.empty, s
@@ -85,12 +94,12 @@ let inline map ([<InlineIfLambda>] proj) ([<InlineIfLambda>] s1) =
8594
8695/// Get the context value
8796let inline getCtx < 'c > () : SigStream < 'c , 'c , unit > =
88- fun s ctx -> Seq.singleton ctx, s
97+ fun s ctx -> [| ctx |] :> seq <_> , s
8998
9099/// Get the state controller of this block
91100let inline getState < 'c , 's > () : SigStream < StateController < 's >, 'c , 's > =
92101 fun state ctx ->
93- Seq.singleton state, state
102+ [| state |] :> seq <_> , state
94103
95104/// Use a memoized value (lazy initialization)
96105let inline useMemoWith ( [<InlineIfLambda>] initializer ) : SigStream < 'a , 'c , 'a > =
@@ -100,7 +109,7 @@ let inline useMemoWith ([<InlineIfLambda>] initializer) : SigStream<'a,'c,'a> =
100109 | ValueNone -> initializer()
101110 | ValueSome v -> v
102111 state.Set( value)
103- Seq.singleton value, state
112+ [| value |] :> seq <_> , state
104113
105114let useMemo ( value : 'a ) : SigStream < 'a , 'c , 'a > =
106115 fun ( state : StateController < 'a >) ctx ->
@@ -109,7 +118,7 @@ let useMemo (value: 'a) : SigStream<'a,'c,'a> =
109118 | ValueNone -> value
110119 | ValueSome v -> v
111120 state.Set( v)
112- Seq.singleton v , state
121+ [| v |] :> seq <_> , state
113122
114123/// Mutable value for local state within streams
115124type MutableValue < 's >( initValue : 's ) =
@@ -159,14 +168,23 @@ module Eval =
159168 toSeqWith 1000 getCtx stream
160169
161170 /// Evaluate n samples
162- let inline run n getCtx stream =
163- toSeq getCtx stream |> Seq.take n |> Seq.toList
171+ let inline run ( n : int ) getCtx stream =
172+ let state = StateController( ValueNone)
173+ let results = ResizeArray<_>( n)
174+ let mutable i = 0
175+ while results.Count < n do
176+ let ctx = getCtx i
177+ i <- i + 1
178+ let vs , _ = stream state ctx
179+ for v in vs do
180+ if results.Count < n then results.Add( v)
181+ Seq.toList results
164182
165183 /// Evaluate with input sequence
166184 let inline runWith ( inputs : seq < _ >) stream =
167185 let state = StateController( ValueNone)
168- inputs
169- |> Seq.collect ( fun ctx ->
186+ let results = ResizeArray <_>()
187+ for ctx in inputs do
170188 let vs , _ = stream state ctx
171- vs )
172- |> Seq.toList
189+ for v in vs do results.Add ( v )
190+ Seq.toList results
0 commit comments