Skip to content

Commit af89a30

Browse files
authored
Merge pull request #1418 from jackmott/fast-array-partition
Fast array partition
2 parents 03ce330 + 5f34f10 commit af89a30

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

src/fsharp/FSharp.Core/array.fs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -487,25 +487,26 @@ namespace Microsoft.FSharp.Collections
487487
checkNonNull "array" array
488488
let res = Array.zeroCreateUnchecked array.Length
489489
let mutable count = 0
490-
for i = 0 to array.Length - 1 do
491-
match f array.[i] with
490+
for x in array do
491+
match f x with
492492
| None -> ()
493493
| Some b -> res.[count] <- b
494494
count <- count + 1
495495
Array.subUnchecked 0 count res
496496

497+
497498
[<CompiledName("Filter")>]
498499
let filter f (array: _[]) =
499500
checkNonNull "array" array
500501
let res = Array.zeroCreateUnchecked array.Length
501502
let mutable count = 0
502-
for i = 0 to array.Length - 1 do
503-
let x = array.[i]
503+
for x in array do
504504
if f x then
505505
res.[count] <- x
506506
count <- count + 1
507507
Array.subUnchecked 0 count res
508508

509+
509510
[<CompiledName("Where")>]
510511
let where f (array: _[]) = filter f array
511512

@@ -523,12 +524,26 @@ namespace Microsoft.FSharp.Collections
523524
[<CompiledName("Partition")>]
524525
let partition f (array: _[]) =
525526
checkNonNull "array" array
526-
let res1 = List<_>() // ResizeArray
527-
let res2 = List<_>() // ResizeArray
528-
for i = 0 to array.Length - 1 do
529-
let x = array.[i]
530-
if f x then res1.Add(x) else res2.Add(x)
531-
res1.ToArray(), res2.ToArray()
527+
let res = Array.zeroCreateUnchecked array.Length
528+
let mutable upCount = 0
529+
let mutable downCount = array.Length-1
530+
for x in array do
531+
if f x then
532+
res.[upCount] <- x
533+
upCount <- upCount + 1
534+
else
535+
res.[downCount] <- x
536+
downCount <- downCount - 1
537+
538+
let res1 = Array.subUnchecked 0 upCount res
539+
let res2 = Array.zeroCreateUnchecked (array.Length - upCount)
540+
541+
downCount <- array.Length-1
542+
for i = 0 to res2.Length-1 do
543+
res2.[i] <- res.[downCount]
544+
downCount <- downCount - 1
545+
546+
res1 , res2
532547

533548
[<CompiledName("Find")>]
534549
let find f (array: _[]) =
@@ -1161,4 +1176,4 @@ namespace Microsoft.FSharp.Collections
11611176
iFalse <- iFalse + 1
11621177

11631178
(trueResult, falseResult)
1164-
#endif
1179+
#endif

0 commit comments

Comments
 (0)