Created
February 14, 2013 03:03
-
-
Save GregRos/4950285 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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