Skip to content

Commit db7279f

Browse files
committed
ArrayCollector/allocations
1 parent 7e14c29 commit db7279f

File tree

1 file changed

+54
-40
lines changed
  • src/FsToolkit.ErrorHandling

1 file changed

+54
-40
lines changed

src/FsToolkit.ErrorHandling/Seq.fs

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
[<RequireQualifiedAccess>]
66
module FsToolkit.ErrorHandling.Seq
77

8+
open Microsoft.FSharp.Core.CompilerServices
9+
810
/// <summary>
911
/// Applies a function to each element of a sequence and returns a single result
1012
/// </summary>
@@ -24,20 +26,21 @@ let inline traverseResultM'
2426
| Error e -> Error e
2527
| Ok initialSuccesses ->
2628

27-
let oks = ResizeArray(initialSuccesses)
28-
let mutable ok = true
29+
let oks = ArrayCollector()
30+
oks.AddMany initialSuccesses
2931
let mutable err = Unchecked.defaultof<'error>
32+
let mutable ok = true
3033
use e = xs.GetEnumerator()
3134

3235
while ok
3336
&& e.MoveNext() do
3437
match f e.Current with
3538
| Ok r -> oks.Add r
3639
| Error e ->
37-
ok <- false
3840
err <- e
41+
ok <- false
3942

40-
if ok then Ok(oks.ToArray()) else Error err
43+
if ok then Ok(oks.Close()) else Error err
4144

4245
/// <summary>
4346
/// Applies a function to each element of a sequence and returns a single result
@@ -74,28 +77,31 @@ let inline traverseResultA'
7477

7578
match state with
7679
| Error failuresToDate ->
77-
let errs = ResizeArray(failuresToDate)
80+
let errs = ArrayCollector()
81+
errs.AddMany failuresToDate
7882

7983
for x in xs do
8084
match f x with
81-
| Ok _ -> () // as the initial state was failure, oks are irrelevant
8285
| Error e -> errs.Add e
86+
| Ok _ -> () // as the initial state was failure, oks are irrelevant
8387

84-
Error(errs.ToArray())
88+
Error(errs.Close())
8589
| Ok initialSuccesses ->
8690

87-
let oks = ResizeArray(initialSuccesses)
88-
let errs = ResizeArray()
91+
let oks = ArrayCollector()
92+
oks.AddMany initialSuccesses
93+
let errs = ArrayCollector()
94+
let mutable ok = true
8995

9096
for x in xs do
9197
match f x with
92-
| Error e -> errs.Add e
93-
| Ok r when errs.Count = 0 -> oks.Add r
98+
| Ok r when ok -> oks.Add r
9499
| Ok _ -> () // no point saving results we won't use given the end result will be Error
100+
| Error e ->
101+
errs.Add e
102+
ok <- false
95103

96-
match errs.ToArray() with
97-
| [||] -> Ok(oks.ToArray())
98-
| errs -> Error errs
104+
if ok then Ok(oks.Close()) else Error(errs.Close())
99105

100106
/// <summary>
101107
/// Applies a function to each element of a sequence and returns a single result
@@ -133,20 +139,21 @@ let inline traverseAsyncResultM'
133139
match! state with
134140
| Error e -> return Error e
135141
| Ok initialSuccesses ->
136-
let oks = ResizeArray(initialSuccesses)
137-
let mutable ok = true
142+
let oks = ArrayCollector()
143+
oks.AddMany initialSuccesses
138144
let mutable err = Unchecked.defaultof<'error>
145+
let mutable ok = true
139146
use e = xs.GetEnumerator()
140147

141148
while ok
142149
&& e.MoveNext() do
143150
match! f e.Current with
144151
| Ok r -> oks.Add r
145152
| Error e ->
146-
ok <- false
147153
err <- e
154+
ok <- false
148155

149-
return if ok then Ok(oks.ToArray()) else Error err
156+
return if ok then Ok(oks.Close()) else Error err
150157
}
151158

152159
/// <summary>
@@ -187,20 +194,21 @@ let inline traverseTaskResultM'
187194
match! state with
188195
| Error e -> return Error e
189196
| Ok initialSuccesses ->
190-
let oks = ResizeArray(initialSuccesses)
191-
let mutable ok = true
197+
let oks = ArrayCollector()
198+
oks.AddMany initialSuccesses
192199
let mutable err = Unchecked.defaultof<'error>
200+
let mutable ok = true
193201
use e = xs.GetEnumerator()
194202

195203
while ok
196204
&& e.MoveNext() do
197205
match! f e.Current with
198206
| Ok r -> oks.Add r
199207
| Error e ->
200-
ok <- false
201208
err <- e
209+
ok <- false
202210

203-
return if ok then Ok(oks.ToArray()) else Error err
211+
return if ok then Ok(oks.Close()) else Error err
204212
}
205213

206214
/// <summary>
@@ -241,28 +249,31 @@ let inline traverseAsyncResultA'
241249
async {
242250
match! state with
243251
| Error failuresToDate ->
244-
let errs = ResizeArray(failuresToDate)
252+
let errs = ArrayCollector()
253+
errs.AddMany failuresToDate
245254

246255
for x in xs do
247256
match! f x with
248257
| Ok _ -> () // as the initial state was failure, oks are irrelevant
249258
| Error e -> errs.Add e
250259

251-
return Error(errs.ToArray())
260+
return Error(errs.Close())
252261
| Ok initialSuccesses ->
253262

254-
let oks = ResizeArray(initialSuccesses)
255-
let errs = ResizeArray()
263+
let oks = ArrayCollector()
264+
oks.AddMany initialSuccesses
265+
let mutable ok = true
266+
let errs = ArrayCollector()
256267

257268
for x in xs do
258269
match! f x with
259-
| Error e -> errs.Add e
260-
| Ok r when errs.Count = 0 -> oks.Add r
270+
| Ok r when ok -> oks.Add r
261271
| Ok _ -> () // no point saving results we won't use given the end result will be Error
272+
| Error e ->
273+
errs.Add e
274+
ok <- false
262275

263-
match errs.ToArray() with
264-
| [||] -> return Ok(oks.ToArray())
265-
| errs -> return Error errs
276+
return if ok then Ok(oks.Close()) else Error(errs.Close())
266277
}
267278

268279
/// <summary>
@@ -300,8 +311,9 @@ let inline traverseOptionM'
300311

301312
match state with
302313
| None -> None
303-
| Some values ->
304-
let values = ResizeArray(values)
314+
| Some initialValues ->
315+
let values = ArrayCollector()
316+
values.AddMany initialValues
305317
let mutable ok = true
306318
use enumerator = xs.GetEnumerator()
307319

@@ -311,7 +323,7 @@ let inline traverseOptionM'
311323
| Some value -> values.Add value
312324
| None -> ok <- false
313325

314-
if ok then Some(values.ToArray()) else None
326+
if ok then Some(values.Close()) else None
315327

316328
/// <summary>
317329
/// Applies a function to each element of a sequence and returns a single option
@@ -348,8 +360,9 @@ let inline traverseAsyncOptionM'
348360
async {
349361
match! state with
350362
| None -> return None
351-
| Some values ->
352-
let values = ResizeArray(values)
363+
| Some initialValues ->
364+
let values = ArrayCollector()
365+
values.AddMany initialValues
353366
let mutable ok = true
354367
use enumerator = xs.GetEnumerator()
355368

@@ -359,7 +372,7 @@ let inline traverseAsyncOptionM'
359372
| Some value -> values.Add value
360373
| None -> ok <- false
361374

362-
return if ok then Some(values.ToArray()) else None
375+
return if ok then Some(values.Close()) else None
363376
}
364377

365378
/// <summary>
@@ -399,8 +412,9 @@ let inline traverseVOptionM'
399412

400413
match state with
401414
| ValueNone -> ValueNone
402-
| ValueSome values ->
403-
let values = ResizeArray(values)
415+
| ValueSome initialValues ->
416+
let values = ArrayCollector()
417+
values.AddMany initialValues
404418
let mutable ok = true
405419
use enumerator = xs.GetEnumerator()
406420

@@ -410,7 +424,7 @@ let inline traverseVOptionM'
410424
| ValueSome value -> values.Add value
411425
| ValueNone -> ok <- false
412426

413-
if ok then ValueSome(values.ToArray()) else ValueNone
427+
if ok then ValueSome(values.Close()) else ValueNone
414428

415429
/// <summary>
416430
/// Applies a function to each element of a sequence and returns a single voption

0 commit comments

Comments
 (0)