未验证 提交 107878ba 编写于 作者: T Tomas Grosup 提交者: GitHub

Array.Parallel extensions - filter, zip (#14916)

* zip function added

* Array.Parallel.filter
上级 08fe57c8
......@@ -2098,6 +2098,31 @@ module Array =
yield new ArraySegment<'T>(array, offset, maxIdxExclusive - offset)
|]
[<CompiledName("Zip")>]
let zip (array1: _[]) (array2: _[]) =
checkNonNull "array1" array1
checkNonNull "array2" array2
let len1 = array1.Length
if len1 <> array2.Length then
invalidArgDifferentArrayLength "array1" len1 "array2" array2.Length
let res = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len1
let inputChunks = createPartitionsUpTo array1.Length array1
Parallel.For(
0,
inputChunks.Length,
fun chunkIdx ->
let chunk = inputChunks[chunkIdx]
for elemIdx = chunk.Offset to (chunk.Offset + chunk.Count - 1) do
res[elemIdx] <- (array1[elemIdx], array2[elemIdx])
)
|> ignore
res
let inline groupByImplParallel
(comparer: IEqualityComparer<'SafeKey>)
([<InlineIfLambda>] keyf: 'T -> 'SafeKey)
......@@ -2213,8 +2238,7 @@ module Array =
Parallel.For(0, count, (fun i -> result.[i] <- initializer i)) |> ignore
result
[<CompiledName("Partition")>]
let partition predicate (array: 'T[]) =
let countAndCollectTrueItems predicate (array: 'T[]) =
checkNonNull "array" array
let inputLength = array.Length
......@@ -2237,10 +2261,28 @@ module Array =
)
|> ignore
trueLength, isTrue
[<CompiledName("Filter")>]
let filter predicate (array: 'T[]) =
let trueLength, isTrue = countAndCollectTrueItems predicate array
let res = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked trueLength
let mutable resIdx = 0
for i = 0 to isTrue.Length - 1 do
if isTrue.[i] then
res.[resIdx] <- array.[i]
resIdx <- resIdx + 1
res
[<CompiledName("Partition")>]
let partition predicate (array: 'T[]) =
let trueLength, isTrue = countAndCollectTrueItems predicate array
let res1 = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked trueLength
let res2 =
Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (inputLength - trueLength)
Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (array.Length - trueLength)
let mutable iTrue = 0
let mutable iFalse = 0
......
......@@ -3491,3 +3491,49 @@ module Array =
/// </example>
[<CompiledName("Partition")>]
val partition: predicate:('T -> bool) -> array:'T[] -> 'T[] * 'T[]
/// <summary>Combines the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an <c>ArgumentException</c> is
/// raised.</summary>
///
/// <param name="array1">The first input array.</param>
/// <param name="array2">The second input array.</param>
///
/// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
/// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
///
/// <returns>The array of tupled elements.</returns>
///
/// <example id="para-zip-1">
/// <code lang="fsharp">
/// let numbers = [|1; 2|]
/// let names = [|"one"; "two"|]
///
/// Array.Parallel.zip numbers names
/// </code>
/// Evaluates to <c>[| (1, "one"); (2, "two") |]</c>.
/// </example>
[<CompiledName("Zip")>]
[<Experimental("Experimental library feature, requires '--langversion:preview'")>]
val zip: array1:'T1[] -> array2:'T2[] -> ('T1 * 'T2)[]
/// <summary>Returns a new collection containing only the elements of the collection
/// for which the given predicate returns <c>true</c>.</summary>
///
/// <param name="predicate">The function to test the input elements.</param>
/// <param name="array">The input array.</param>
///
/// <returns>An array containing the elements for which the given predicate returns true.</returns>
///
/// <exception cref="T:System.ArgumentNullException">Thrown when the input array is <c>null</c>.</exception>
///
/// <example id="para-filter-1">
/// <code lang="fsharp">
/// let inputs = [| 1; 2; 3; 4 |]
///
/// inputs |> Array.Parallel.filter (fun elm -> elm % 2 = 0)
/// </code>
/// Evaluates to <c>[| 2; 4 |]</c>
/// </example>
[<CompiledName("Filter")>]
[<Experimental("Experimental library feature, requires '--langversion:preview'")>]
val filter: predicate:('T -> bool) -> array:'T[] -> 'T[]
\ No newline at end of file
......@@ -46,11 +46,14 @@ Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] Gr
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[])
......
......@@ -40,18 +40,19 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32
Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]])
Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32)
Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T)
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[])
......
......@@ -42,15 +42,17 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, I
Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T)
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean Exists[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Boolean ForAll[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[])
......
......@@ -46,11 +46,13 @@ Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] Gr
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[])
Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[])
......
......@@ -709,6 +709,20 @@ type ArrayModule() =
()
[<Fact>]
member this.ParallelFilter () =
let assertSameBehavior predicate arr =
let sequentialZip = Array.filter predicate arr
let paraZip = Array.Parallel.filter predicate arr
Assert.AreEqual(sequentialZip, paraZip)
[| 1..20 |] |> assertSameBehavior (fun x -> x%5 = 0)
[|"Lists"; "are"; "a"; "commonly"; "data";"structor" |] |> assertSameBehavior (fun x -> x.Length > 4)
[| |] |> assertSameBehavior (fun x -> x%5 = 0)
let nullArr = null:int[]
CheckThrowsArgumentNullException (fun () -> Array.Parallel.filter (fun x -> x%5 = 0) nullArr |> ignore)
[<Fact>]
member this.Filter2 () =
// The Array.filter algorithm uses a bitmask as a temporary storage mechanism
......
......@@ -1259,7 +1259,22 @@ type ArrayModule2() =
// len1 <> len2
CheckThrowsArgumentException(fun () -> Array.zip [|1..10|] [|2..20|] |> ignore)
()
[<Fact>]
member this.ParallelZip() =
let assertSameBehaviour arr1 arr2 =
let sequentialZip = Array.zip arr1 arr2
let paraZip = Array.Parallel.zip arr1 arr2
Assert.AreEqual(sequentialZip, paraZip)
assertSameBehaviour [|1..3|] [|2..2..6|]
assertSameBehaviour[|"A"; "B"; "C" ; "D" |] [|"a";"b";"c";"d"|]
assertSameBehaviour[||] [||]
// null array
let nullArr = null:string[]
CheckThrowsArgumentNullException (fun () -> Array.Parallel.zip nullArr nullArr |> ignore)
// len1 <> len2
CheckThrowsArgumentException(fun () -> Array.Parallel.zip [|1..10|] [|2..20|] |> ignore)
[<Fact>]
member this.Zip3() =
......
......@@ -254,7 +254,8 @@ let filter<'a when 'a : equality> (xs : 'a []) predicate =
let s = xs |> Seq.filter predicate
let l = xs |> List.ofArray |> List.filter predicate
let a = xs |> Array.filter predicate
Seq.toArray s = a && List.toArray l = a
let pa = xs |> Array.Parallel.filter predicate
pa = a && Seq.toArray s = a && List.toArray l = a
[<Fact>]
let ``filter is consistent`` () =
......@@ -1288,9 +1289,10 @@ let zip<'a when 'a : equality> (xs':('a*'a) []) =
let xs = Array.map fst xs'
let xs2 = Array.map snd xs'
let s = runAndCheckErrorType (fun () -> Seq.zip xs xs2 |> Seq.toArray)
let l = runAndCheckErrorType (fun () -> List.zip (List.ofSeq xs) (List.ofSeq xs2) |> List.toArray)
let a = runAndCheckErrorType (fun () -> Array.zip (Array.ofSeq xs) (Array.ofSeq xs2))
consistency "zip" s l a
let l = runAndCheckErrorType (fun () -> List.zip (List.ofArray xs) (List.ofArray xs2) |> List.toArray)
let a = runAndCheckErrorType (fun () -> Array.zip xs xs2)
let pa = runAndCheckErrorType (fun () -> Array.Parallel.zip xs xs2)
consistencyIncludingParallel "zip" s l a pa
[<Fact>]
let ``zip is consistent for collections with equal length`` () =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册