0 people like it.
Like the snippet!
Active Pattern Performance with Structs
Demonstrating poor active pattern performance
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
|
[<Struct>]
type ArrayAsList<'a> =
val arr : 'a []
val idx : int
new (inarr: 'a []) = { arr = inarr; idx = 0 }
new (inarr: 'a [], inidx: int) = { arr = inarr; idx = inidx }
member inline t.IsEmpty = t.idx >= t.arr.Length
member inline t.Head = t.arr.[t.idx]
member inline t.Tail = ArrayAsList<_>(t.arr, t.idx + 1)
let inline (|EmptyArrayAsList|UnconsArrayAsList|) (all: ArrayAsList<_>) =
if all.IsEmpty then EmptyArrayAsList else UnconsArrayAsList(all.Head, all.Tail)
let inline (|EmptyArrayAsList'|_|) (all: ArrayAsList<_>) =
if all.IsEmpty then Some() else None
let inline (|UnconsArrayAsList'|_|) (all: ArrayAsList<_>) =
if all.IsEmpty then None else Some(all.Head, all.Tail)
let x_arr = ArrayAsList([|1 .. 10000000|])
let x_list = [1 .. 10000000]
#time
let rec decomposeList l cnt =
match l with
| h :: t -> decomposeList t (cnt + 1)
| [] -> cnt
decomposeList x_list 0
// Real: 00:00:00.017, CPU: 00:00:00.015, GC gen0: 0, gen1: 0, gen2: 0
let rec decomposeAAL l cnt =
match l with
| UnconsArrayAsList(h, t) -> decomposeAAL t (cnt + 1)
| EmptyArrayAsList -> cnt
decomposeAAL x_arr 0
// Real: 00:00:00.179, CPU: 00:00:00.171, GC gen0: 85, gen1: 1, gen2: 0
let rec decomposeAAL' (l: ArrayAsList<_>) cnt =
if l.IsEmpty then cnt
else decomposeAAL' l.Tail (cnt + 1)
decomposeAAL' x_arr 0
// Real: 00:00:00.034, CPU: 00:00:00.031, GC gen0: 0, gen1: 0, gen2: 0
let rec decomposeAAL'' l cnt =
match l with
| UnconsArrayAsList'(h, t) -> decomposeAAL'' t (cnt + 1)
| EmptyArrayAsList' -> cnt
| _ -> failwith "nope"
decomposeAAL'' x_arr 0
// Real: 00:00:00.183, CPU: 00:00:00.187, GC gen0: 86, gen1: 1, gen2: 0
|
Multiple items
type StructAttribute =
inherit Attribute
new : unit -> StructAttribute
Full name: Microsoft.FSharp.Core.StructAttribute
--------------------
new : unit -> StructAttribute
Multiple items
type ArrayAsList<'a> =
struct
new : inarr:'a [] -> ArrayAsList<'a>
new : inarr:'a [] * inidx:int -> ArrayAsList<'a>
val arr: 'a []
val idx: int
member Head : 'a
member IsEmpty : bool
member Tail : ArrayAsList<'a>
end
Full name: Script.ArrayAsList<_>
--------------------
ArrayAsList()
new : inarr:'a [] -> ArrayAsList<'a>
new : inarr:'a [] * inidx:int -> ArrayAsList<'a>
ArrayAsList.arr: 'a []
ArrayAsList.idx: int
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val inarr : 'a []
val inidx : int
val t : byref<ArrayAsList<'a>>
member ArrayAsList.IsEmpty : bool
Full name: Script.ArrayAsList`1.IsEmpty
member ArrayAsList.Head : 'a
Full name: Script.ArrayAsList`1.Head
member ArrayAsList.Tail : ArrayAsList<'a>
Full name: Script.ArrayAsList`1.Tail
val all : ArrayAsList<'a>
property ArrayAsList.IsEmpty: bool
property ArrayAsList.Head: 'a
property ArrayAsList.Tail: ArrayAsList<'a>
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
val x_arr : ArrayAsList<int>
Full name: Script.x_arr
val x_list : int list
Full name: Script.x_list
val decomposeList : l:'a list -> cnt:int -> int
Full name: Script.decomposeList
val l : 'a list
val cnt : int
val h : 'a
val t : 'a list
val decomposeAAL : l:ArrayAsList<'a> -> cnt:int -> int
Full name: Script.decomposeAAL
val l : ArrayAsList<'a>
active recognizer UnconsArrayAsList: ArrayAsList<'a> -> Choice<unit,('a * ArrayAsList<'a>)>
Full name: Script.( |EmptyArrayAsList|UnconsArrayAsList| )
val t : ArrayAsList<'a>
active recognizer EmptyArrayAsList: ArrayAsList<'a> -> Choice<unit,('a * ArrayAsList<'a>)>
Full name: Script.( |EmptyArrayAsList|UnconsArrayAsList| )
val decomposeAAL' : l:ArrayAsList<'a> -> cnt:int -> int
Full name: Script.decomposeAAL'
val decomposeAAL'' : l:ArrayAsList<'a> -> cnt:int -> int
Full name: Script.decomposeAAL''
active recognizer UnconsArrayAsList': ArrayAsList<'a> -> ('a * ArrayAsList<'a>) option
Full name: Script.( |UnconsArrayAsList'|_| )
active recognizer EmptyArrayAsList': ArrayAsList<'a> -> unit option
Full name: Script.( |EmptyArrayAsList'|_| )
val failwith : message:string -> 'T
Full name: Microsoft.FSharp.Core.Operators.failwith
More information