Skip to content

Commit

Permalink
Inline List.iter/List.iteri for performance (dotnet#8176)
Browse files Browse the repository at this point in the history
  • Loading branch information
TIHan authored and nosami committed Feb 22, 2021
1 parent abf9ebb commit ad7bd70
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 17 deletions.
6 changes: 4 additions & 2 deletions src/fsharp/FSharp.Core/list.fs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ namespace Microsoft.FSharp.Collections
loop ([], state) (rev list)

[<CompiledName("Iterate")>]
let iter action list = Microsoft.FSharp.Primitives.Basics.List.iter action list
let inline iter action (list:'T list) = for x in list do action x

[<CompiledName("Distinct")>]
let distinct (list:'T list) = Microsoft.FSharp.Primitives.Basics.List.distinctWithComparer HashIdentity.Structural<'T> list
Expand Down Expand Up @@ -164,7 +164,9 @@ namespace Microsoft.FSharp.Collections
let takeWhile predicate (list: 'T list) = Microsoft.FSharp.Primitives.Basics.List.takeWhile predicate list

[<CompiledName("IterateIndexed")>]
let iteri action list = Microsoft.FSharp.Primitives.Basics.List.iteri action list
let inline iteri action (list: 'T list) =
let mutable n = 0
for x in list do action n x; n <- n + 1

[<CompiledName("Initialize")>]
let init length initializer = Microsoft.FSharp.Primitives.Basics.List.init length initializer
Expand Down
4 changes: 2 additions & 2 deletions src/fsharp/FSharp.Core/list.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ namespace Microsoft.FSharp.Collections
/// <param name="action">The function to apply to elements from the input list.</param>
/// <param name="list">The input list.</param>
[<CompiledName("Iterate")>]
val iter: action:('T -> unit) -> list:'T list -> unit
val inline iter: action:('T -> unit) -> list:'T list -> unit

/// <summary>Applies the given function to two collections simultaneously. The
/// collections must have identical size.</summary>
Expand All @@ -395,7 +395,7 @@ namespace Microsoft.FSharp.Collections
/// <param name="action">The function to apply to the elements of the list along with their index.</param>
/// <param name="list">The input list.</param>
[<CompiledName("IterateIndexed")>]
val iteri: action:(int -> 'T -> unit) -> list:'T list -> unit
val inline iteri: action:(int -> 'T -> unit) -> list:'T list -> unit

/// <summary>Applies the given function to two collections simultaneously. The
/// collections must have identical size. The integer passed to the
Expand Down
11 changes: 0 additions & 11 deletions src/fsharp/FSharp.Core/local.fs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ module internal List =
[<SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")>]
let nonempty x = match x with [] -> false | _ -> true

let rec iter f x = match x with [] -> () | h :: t -> f h; iter f t

// optimized mutation-based implementation. This code is only valid in fslib, where mutation of private
// tail cons cells is permitted in carefully written library code.
let inline setFreshConsTail cons t = cons.( :: ).1 <- t
Expand Down Expand Up @@ -499,15 +497,6 @@ module internal List =
else
filter predicate t

let iteri action x =
let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(action)
let rec loop n x =
match x with
| [] -> ()
| h :: t -> f.Invoke(n, h); loop (n+1) t

loop 0 x

// optimized mutation-based implementation. This code is only valid in fslib, where mutation of private
// tail cons cells is permitted in carefully written library code.
let rec concatToFreshConsTail cons h1 l =
Expand Down
2 changes: 0 additions & 2 deletions src/fsharp/FSharp.Core/local.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ module internal List =
val distinctWithComparer : System.Collections.Generic.IEqualityComparer<'T> -> 'T list -> 'T list
val distinctByWithComparer : System.Collections.Generic.IEqualityComparer<'Key> -> ('T -> 'Key) -> list:'T list -> 'T list when 'Key : equality
val init : int -> (int -> 'T) -> 'T list
val iter : ('T -> unit) -> 'T list -> unit
val filter : predicate:('T -> bool) -> 'T list -> 'T list
val collect : ('T -> 'U list) -> 'T list -> 'U list
val partition : predicate:('T -> bool) -> 'T list -> 'T list * 'T list
Expand All @@ -48,7 +47,6 @@ module internal List =
val exists : predicate:('T -> bool) -> 'T list -> bool
val rev: 'T list -> 'T list
val concat : seq<'T list> -> 'T list
val iteri : action:(int -> 'T -> unit) -> 'T list -> unit
val unfold : ('State -> ('T * 'State) option) -> 'State -> 'T list
val unzip : ('T1 * 'T2) list -> 'T1 list * 'T2 list
val unzip3 : ('T1 * 'T2 * 'T3) list -> 'T1 list * 'T2 list * 'T3 list
Expand Down

0 comments on commit ad7bd70

Please sign in to comment.