Skip to content

Instantly share code, notes, and snippets.

@GregRos
Created February 14, 2013 03:03
Show Gist options
  • Save GregRos/4950285 to your computer and use it in GitHub Desktop.
Save GregRos/4950285 to your computer and use it in GitHub Desktop.
// Learn more about F# at http://fsharp.net
// See the 'F# Tutorial' project for more help.
module SoldiTesting.Main
open System.Numerics
open System.Diagnostics
open System
module VariousLists =
type lenList<'a> =
private
| Nil
| LenList of 'a * lenList<'a> * int
with
member this.Length =
match this with
| Nil -> 0
| LenList(_,_,c) -> c
static member Empty : lenList<'a>= Nil
static member Cons (hd : 'a) (tl : lenList<'a>) = LenList(hd,tl,tl.Length + 1)
member this.Head =
match this with
| Nil -> failwith "The list is empty."
| LenList(h,_,_) -> h
member this.Tail =
match this with
| Nil -> failwith "The list is empty."
| LenList(_,t,_) -> t
type sumList =
private
| Nil
| SumList of int * sumList * int
with
member this.Length =
let rec len prev lst =
match lst with
| Nil -> prev
| SumList(_,t,_) -> len (prev + 1) t
len 0 this
member this.Sum =
match this with
| Nil -> 0
| SumList(_,_,c) -> c
static member Empty : sumList = Nil
static member Cons (hd : int) (tl : sumList) = SumList(hd,tl,tl.Sum + hd)
member this.Head =
match this with
| Nil -> failwith "The list is empty."
| SumList(h,_,_) -> h
member this.Tail =
match this with
| Nil -> failwith "The list is empty."
| SumList(_,t,_) -> t
type simpleList<'a> =
private
| Nil
| SimpleList of 'a * 'a simpleList
with
member this.Length =
let rec len prev lst =
match lst with
| Nil -> prev
| SimpleList(_,t) -> len (prev + 1) t
len 0 this
static member Empty = Nil
static member Cons (hd : 'a)( tl : 'a simpleList) = SimpleList(hd,tl)
//member this.Cons (hd : 'a) = SimpleList(hd,this)
member this.Head =
match this with
| Nil -> failwith "The list is empty."
| SimpleList(h,_) -> h
member this.Tail =
match this with
| Nil -> failwith "The list is empty."
| SimpleList(_,t) -> t
let inline (|Stack|) (s : ^a when ^a : (static member Empty : ^a) and ^a : (static member Cons : ^b -> ^a -> ^a) and ^a : (member Tail : ^a) and ^a : (member Head : ^b) and ^s : (member Length : int)) = s
module List' =
let inline empty() = (^s : (static member Empty : ^s) () )
let inline cons (head : ^b) (Stack(stk : ^s)) = (^s : (static member Cons : ^b -> ^s -> ^s) (head,stk))
let inline tail (Stack(stk : ^s)) = (^s : (member Tail : ^s) stk)
let inline head (Stack(stk : ^s)) = (^s : (member Head : _) stk)
let inline length (Stack(stk : ^s)) = (^s : (member Length : int) stk)
let inline isEmpty (Stack(stk)) = (stk = empty())
let inline rev (Stack(stk : ^s)) =
let mutable stk1 = stk
let mutable stk2 = empty() : ^s
while stk1 |> isEmpty |> not do
stk2 <- stk2 |> cons (stk1 |> head)
stk1 <- stk1 |> tail
stk2
let inline map (mapping : _ -> _) (Stack(stk : ^s)) =
let mutable stkr = stk |> rev
let mutable stkmp = empty() : ^s
while stkr |> isEmpty |> not do
stkmp <- stkmp |> cons (stkr |> head |> mapping)
stkr <- stkr |> tail
stkmp
let inline toArray (Stack(stk)) =
let mutable stk = stk
let len = stk |> length
let arr = Array.zeroCreate len
for i in len .. 0 .. -1 do
arr.[i] <- stk |> head
stk <- stk |> tail
arr
let inline toList (Stack(stk)) =
let mutable lst : ^b list= []
let mutable stk = stk
while stk |> isEmpty |> not do
lst <- List.Cons(stk |> head,lst)
stk <- stk |> tail
lst |> List.rev
let inline consList lst (Stack(stk)) =
let mutable lst = lst
let mutable stk = stk
while lst |> List.isEmpty |> not do
stk <- stk |> cons (lst.Head)
lst <- lst.Tail
stk
let inline consSeq sq (Stack(stk)) =
let mutable stk = stk
for item in sq do
stk <- stk |> cons item
stk
let inline toSeq (Stack(stk)) =
let rStk = ref stk
seq {
while !rStk |> isEmpty |> not do
yield !rStk |> head
rStk := !rStk |> tail
}
let inline ofList lst = empty() |> consList lst |> rev
let inline ofSeq sq = empty() |> consSeq sq |> rev
open VariousLists
[<EntryPoint>]
let rec main argv =
let mutable lst = []
let mutable stk = List'.empty() : int lenList
let sw = Stopwatch()
do GC.Collect()
do printfn "Doing custom list"
do sw.Start()
for i in 0 .. 1000000 do
stk <- lenList<int>.Cons i stk
sw.Stop()
do printfn "%A" sw.Elapsed
do sw.Stop()
do GC.Collect()
do printfn "Doing normal list"
do sw.Restart()
for i in 0 .. 1000000 do
lst <- List<int>.Cons(i,lst)
do sw.Stop()
do printfn "%A" sw.Elapsed
Console.Read() |> ignore
main [| |]
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment