Skip to content

Commit

Permalink
[FSharp] Use InlineIfLambda and FSharpFunc
Browse files Browse the repository at this point in the history
Applies InlineIfLambda or FSharpFunc to various utilities taking function arguments.
  • Loading branch information
hyazinthh committed Apr 3, 2024
1 parent af1c121 commit acb7e71
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 71 deletions.
32 changes: 18 additions & 14 deletions src/Aardvark.Base.FSharp/Datastructures/Mutable/FixedSizeArray.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,26 +59,28 @@ module Arrays =

[<ReflectedDefinition>]
module Arr =
let map (f : 'a -> 'b) (a : Arr<'d, 'a>) : Arr<'d, 'b> =
let inline map ([<InlineIfLambda>] f : 'a -> 'b) (a : Arr<'d, 'a>) : Arr<'d, 'b> =
let result = Array.zeroCreate a.Length
for i in 0..a.Length-1 do
result.[i] <- f a.[i]
Arr<'d,'b>(result)

let fold (f : 's -> 'a -> 's) (seed : 's) (a : Arr<'d, 'a>) : 's =
let inline fold (f : 's -> 'a -> 's) (seed : 's) (a : Arr<'d, 'a>) : 's =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
let mutable result = seed
for i in 0..a.Length-1 do
result <- f result a.[i]
result <- f.Invoke(result, a.[i])
result

let foldBack (f : 'a -> 's -> 's) (seed : 's) (a : Arr<'d, 'a>) : 's =
let inline foldBack (f : 'a -> 's -> 's) (seed : 's) (a : Arr<'d, 'a>) : 's =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
let mutable result = seed
for i in 1..a.Length do
let i = a.Length-i
result <- f a.[i] result
result <- f.Invoke(a.[i], result)
result

let inline sumBy (f : 'a -> 'b) (arr : Arr<'d, 'a>)=
let inline sumBy ([<InlineIfLambda>] f : 'a -> 'b) (arr : Arr<'d, 'a>)=
fold (fun s v -> s + (f v)) GenericValues.zero arr

let inline sum (arr : Arr<'d, 'a>)=
Expand All @@ -96,13 +98,13 @@ module Arrays =

let empty<'d, 'a when 'd :> INatural> : FixedList<'d, 'a> = { storage = Arr<'d, 'a>(); Count = 0 }

let map (f : 'a -> 'b) (l : FixedList<'d, 'a>) : FixedList<'d, 'b> =
let inline map ([<InlineIfLambda>] f : 'a -> 'b) (l : FixedList<'d, 'a>) : FixedList<'d, 'b> =
let result = Arr<'d, 'b>()
for i in 0..l.Count-1 do
result.[i] <- f l.storage.[i]
{ storage =result; Count = l.Count }

let choose (f : 'a -> Option<'b>) (l : FixedList<'d, 'a>) : FixedList<'d, 'b> =
let inline choose ([<InlineIfLambda>] f : 'a -> Option<'b>) (l : FixedList<'d, 'a>) : FixedList<'d, 'b> =
let result = Arr<'d, 'b>()
let mutable count = 0

Expand All @@ -115,19 +117,21 @@ module Arrays =

{ storage = result; Count = count }

let fold (acc : 'a -> 'b -> 'a) (seed : 'a) (l : FixedList<'d, 'b>) : 'a =
let inline fold (acc : 'a -> 'b -> 'a) (seed : 'a) (l : FixedList<'d, 'b>) : 'a =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt acc
let mutable result = seed
for i in 0..l.Count-1 do
result <- acc result l.storage.[i]
result <- f.Invoke(result, l.storage.[i])
result

let foldBack (acc : 'b -> 'a -> 'a) (seed : 'a) (l : FixedList<'d, 'b>) : 'a =
let inline foldBack (acc : 'b -> 'a -> 'a) (seed : 'a) (l : FixedList<'d, 'b>) : 'a =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt acc
let mutable result = seed
for i in 1..l.Count do
result <- acc l.storage.[i - l.Count] result
result <- f.Invoke(l.storage.[i - l.Count], result)
result

let inline sumBy (f : 'a -> 'b) (l : FixedList<'d, 'a>) : 'b =
let inline sumBy ([<InlineIfLambda>] f : 'a -> 'b) (l : FixedList<'d, 'a>) : 'b =
let mutable result = GenericValues.zero
for i in 0..l.Count-1 do
result <- result + f l.storage.[i]
Expand All @@ -139,7 +143,7 @@ module Arrays =
result <- result + l.storage.[i]
result

let filter (l : FixedList<'d, 'a>) (condition : 'a -> bool) : FixedList<'d, 'a> =
let inline filter ([<InlineIfLambda>] condition : 'a -> bool) (l : FixedList<'d, 'a>) : FixedList<'d, 'a> =
let result = Arr<'d, 'a>()
let mutable count = 0

Expand Down
13 changes: 7 additions & 6 deletions src/Aardvark.Base.FSharp/Utilities/Interop/CSharpList.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ module CSharpList =

let inline map (f : 'a -> 'b) (l : List<'a>) = l.Map f

let collect (f : 'a -> seq<'b>) (l : List<'a>) =
let inline collect ([<InlineIfLambda>] f : 'a -> seq<'b>) (l : List<'a>) =
let res = List()
for e in l do
res.AddRange (f e)
res

let choose (f : 'a -> Option<'b>) (l : List<'a>) =
let inline choose ([<InlineIfLambda>] f : 'a -> Option<'b>) (l : List<'a>) =
let res = List()
for e in l do
match f e with
Expand All @@ -29,7 +29,7 @@ module CSharpList =

res

let filter (f : 'a -> bool) (l : List<'a>) =
let inline filter ([<InlineIfLambda>] f : 'a -> bool) (l : List<'a>) =
let res = List()
for e in l do
if f e then res.Add e
Expand All @@ -50,13 +50,14 @@ module CSharpList =

let inline count (l : List<'a>) = l.Count

let iter (f : 'a -> unit) (l : List<'a>) =
let inline iter ([<InlineIfLambda>] f : 'a -> unit) (l : List<'a>) =
for i in 0..l.Count-1 do
f l.[i]

let iteri (f : int -> 'a -> unit) (l : List<'a>) =
let inline iteri (f : int -> 'a -> unit) (l : List<'a>) =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
for i in 0..l.Count-1 do
f i l.[i]
f.Invoke(i, l.[i])


let empty<'a> : List<'a> = List()
Expand Down
18 changes: 12 additions & 6 deletions src/Aardvark.Base.FSharp/Utilities/Interop/Dictionary.fs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ module Dictionary =
d.Clear()

let inline map (f : 'k -> 'a -> 'b) (d : Dictionary<'k, 'a>) =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
let result = Dictionary()
for (KeyValue(k,v)) in d do
result.[k] <- f k v
result.[k] <- f.Invoke(k, v)
result

let inline mapKeys (f : 'k -> 'a -> 'b) (d : Dictionary<'k, 'a>) =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
let result = Dictionary()
for (KeyValue(k,v)) in d do
result.[f k v] <- v
result.[f.Invoke(k, v)] <- v
result

let inline union (dicts : #seq<Dictionary<'k, 'v>>) =
Expand Down Expand Up @@ -145,15 +147,17 @@ module Dict =
#endif

let inline map (f : 'k -> 'a -> 'b) (d : Dict<'k, 'a>) =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
let result = Dict()
for (KeyValue(k,v)) in d do
result.[k] <- f k v
result.[k] <- f.Invoke(k, v)
result

let inline mapKeys (f : 'k -> 'a -> 'b) (d : Dict<'k, 'a>) =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
let result = Dict()
for (KeyValue(k,v)) in d do
result.[f k v] <- v
result.[f.Invoke(k, v)] <- v
result

let inline union (dicts : #seq<Dict<'k, 'v>>) =
Expand Down Expand Up @@ -242,15 +246,17 @@ module SymDict =
d.Clear()

let inline map (f : Symbol -> 'a -> 'b) (d : SymbolDict<'a>) =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
let result = SymbolDict()
for (KeyValue(k,v)) in d do
result.[k] <- f k v
result.[k] <- f.Invoke(k, v)
result

let inline mapKeys (f : Symbol -> 'a -> Symbol) (d : SymbolDict<'a>) =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt f
let result = SymbolDict()
for (KeyValue(k,v)) in d do
result.[f k v] <- v
result.[f.Invoke(k, v)] <- v
result

let inline union (dicts : #seq<SymbolDict<'v>>) =
Expand Down
93 changes: 49 additions & 44 deletions src/Aardvark.Base.FSharp/Utilities/Interop/FSLibExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Prelude =

let inc (a:byref<int>) = a <- a + 1
let dec (a:byref<int>) = a <- a - 1

let inline isNull (a : 'a) =
match a with
| null -> true
Expand All @@ -27,46 +27,47 @@ module Prelude =
(Map.empty, input) ||> Seq.fold union

module Seq =
let iter' (f : 'a -> 'b) (s : seq<'a>) =
let inline iter' ([<InlineIfLambda>] f : 'a -> 'b) (s : seq<'a>) =
for i in s do
f i |> ignore
f i |> ignore

let repeat (n : int) (f : unit -> unit) =
let inline repeat (n : int) ([<InlineIfLambda>] f : unit -> unit) =
for i in 1..n do
f()

let repeat' (n : int) (f : unit -> 'a) =
let inline repeat' (n : int) ([<InlineIfLambda>] f : unit -> 'a) =
for i in 1..n do
f() |> ignore

let partition (f : 'a -> bool) (xs : seq<'a>) =
let inline partition ([<InlineIfLambda>] f : 'a -> bool) (xs : seq<'a>) =
let xs = xs |> Seq.map (fun a -> f a, a) |> Seq.cache

(xs |> Seq.filter (fun (r,v) -> not r) |> Seq.map snd, xs |> Seq.filter (fun (r,v) -> r) |> Seq.map snd)

let chooseOption (f : 'a -> Option<'b>) (xs : seq<Option<'a>>) : seq<Option<'b>> =
let inline chooseOption ([<InlineIfLambda>] f : 'a -> Option<'b>) (xs : seq<Option<'a>>) : seq<Option<'b>> =
seq {
for x in xs do
match x with
| None -> ()
| Some x -> yield f x
}

[<Obsolete("Use Seq.exists instead.")>]
let forany (f : 'a -> bool) (s : seq<'a>) =
let e = s.GetEnumerator()
let mutable r = false
while not r && e.MoveNext() do
if f e.Current then
r <- true
e.Dispose()
r

let foldi (folder : int -> 'State -> 'T -> 'State) (state : 'State) (source : 'T seq) =
((0, state), source) ||> Seq.fold (fun (i, state) x ->
(i + 1), folder i state x
) |> snd

let inline tryPickV chooser (source : seq<'T>) =
Seq.exists f s

let inline foldi (folder : int -> 'State -> 'T -> 'State) (state : 'State) (source : 'T seq) =
use e = source.GetEnumerator()
let f = OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt folder
let mutable state = state
let mutable i = 0

while e.MoveNext() do
state <- f.Invoke(0, state, e.Current)
i <- i + 1

state

let inline tryPickV ([<InlineIfLambda>] chooser) (source : seq<'T>) =
use e = source.GetEnumerator()
let mutable res = ValueNone

Expand All @@ -75,7 +76,7 @@ module Prelude =

res

let inline tryFindV predicate (source: seq<'T>) =
let inline tryFindV ([<InlineIfLambda>] predicate) (source: seq<'T>) =
use e = source.GetEnumerator()
let mutable res = ValueNone

Expand Down Expand Up @@ -140,27 +141,36 @@ module Prelude =
let partition (f : 'a -> bool) (source : list<'a>) =
partitionAcc f source (System.Collections.Generic.List()) (System.Collections.Generic.List())

let foldi (folder : int -> 'State -> 'T -> 'State) (state : 'State) (list : 'T list) =
((0, state), list) ||> List.fold (fun (i, state) x ->
(i + 1), folder i state x
) |> snd
let inline foldi (folder : int -> 'State -> 'T -> 'State) (state : 'State) (list : 'T list) =
match list with
| [] -> state
| _ ->
let f = OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt(folder)
let mutable acc = state
let mutable i = 0

for x in list do
acc <- f.Invoke(i, acc, x)
i <- i + 1

acc

module Array =
let rec private forany' (f : 'a -> bool) (index : int) (a : 'a[]) =
if index >= a.Length then false
else
if f a.[index] then true
else forany' f (index + 1) a

[<Obsolete("Use Array.exists instead.")>]
let forany (f : 'a -> bool) (a : 'a[]) =
forany' f 0 a
Array.exists f a

let foldi (folder : int -> 'State -> 'T -> 'State) (state : 'State) (array : 'T[]) =
((0, state), array) ||> Array.fold (fun (i, state) x ->
(i + 1), folder i state x
) |> snd
let inline foldi (folder : int -> 'State -> 'T -> 'State) (state : 'State) (array : 'T[]) =
let f = OptimizedClosures.FSharpFunc<_, _, _, _>.Adapt(folder)
let mutable state = state

let binarySearch (compare : 'T -> int) (array : 'T[]) =
for i = 0 to array.Length - 1 do
state <- f.Invoke(i, state, array.[i])

state

let inline binarySearch ([<InlineIfLambda>] compare : 'T -> int) (array : 'T[]) =
let rec search (a : int) (b : int) =
if a <= b then
let i = (a + b) / 2
Expand All @@ -174,7 +184,7 @@ module Prelude =

search 0 (array.Length - 1)

let inline tryPickV chooser (array : _[]) =
let inline tryPickV ([<InlineIfLambda>] chooser) (array : _[]) =
let rec loop i =
if i >= array.Length then
ValueNone
Expand All @@ -192,11 +202,6 @@ module Prelude =
let inline dispose v = (^a : (member Dispose : unit -> unit) v)

module Option =
let inline defaultValue (fallback : 'a) (option : Option<'a>) =
match option with
| Some value -> value
| None -> fallback

let inline toValueOption (value : 'T option) =
match value with Some x -> ValueSome x | _ -> ValueNone

Expand Down
2 changes: 1 addition & 1 deletion src/Aardvark.Base.FSharp/Utilities/Interop/HashSet.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module HashSet =
let inline clear (h : HashSet<_>) =
h.Clear()

let inline map f (h : HashSet<_>) =
let inline map ([<InlineIfLambda>] f) (h : HashSet<_>) =
let r = HashSet()
for v in h do r.Add (f v) |> ignore
r
Expand Down

0 comments on commit acb7e71

Please sign in to comment.