Skip to content

Instantly share code, notes, and snippets.

@1tgr
Created February 15, 2013 15:08
Show Gist options
  • Select an option

  • Save 1tgr/4960921 to your computer and use it in GitHub Desktop.

Select an option

Save 1tgr/4960921 to your computer and use it in GitHub Desktop.
Adventures in inlining
module Program
// Copy and paste from the FSharp.Core source code
let inline zeroCreateUnchecked (count:int) =
(# "newarr !0" type ('T) count : 'T array #)
let inline map fn a =
let b = zeroCreateUnchecked (Array.length a)
for i in 0 .. Array.length a - 1 do
b.[i] <- fn a.[i]
b
let numbers = [| 1; 2; 3 |]
let addOne n = n + 1
let one () =
// Our own map function, using the fun keyword
// Everything is inlined; loops like a C# for loop
printfn "%A" (map (fun a -> a + 1) numbers)
let two () =
// Our own map function, using the let keyword and the function defined elsewhere
// Identical to one(). The let keyword makes no difference.
printfn "%A" (map addOne numbers)
let three () =
// Standard Array.map, using the fun keyword
// Everything is inlined, including a null reference check at the start of Array.map, which is
// arguably not needed (the 'numbers' array can't be null).
// The loop syntax ends up being slightly different compared to one(). ILSpy recognises this
// as a while loop, and one() as a for loop.
printfn "%A" (Array.map (fun a -> a + 1) numbers)
let four () =
// Standard Array.map, using the let keyword and the function defined elsewhere
// Idential to three(). The let keyword makes no difference.
printfn "%A" (Array.map addOne numbers)
let five () =
// Sequence syntax, writing the loop body directly
// The compiler generates a hidden class which implements IEnumerable<int>, and generates the
// numbers. It calls Seq.toArray on an instance of this class. The 'a + 1' code is inlined
// inside this class.
printfn "%A" [| for a in numbers -> a + 1 |]
let six () =
// Sequence syntax, calling another function from the loop body
// Identical to three(). The let keyword makes no difference.
printfn "%A" [| for a in numbers -> addOne a |]
one ()
two ()
three ()
four ()
five ()
six ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment