Created
July 21, 2018 01:34
-
-
Save manofstick/275fe8ed62091aec52cd382548719f2a 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
open System | |
type KeyStruct(_1':int, _2':int, _3':int) = struct | |
member this._1 = _1' | |
member this._2 = _2' | |
member this._3 = _3' | |
end | |
type KeyGenericStruct<'a>(_1':'a, _2':'a, _3':'a) = struct | |
member this._1 = _1' | |
member this._2 = _2' | |
member this._3 = _3' | |
end | |
type KeyRecord = { _1 : int; _2 : int; _3 : int } | |
type KeyGenericRecord<'a> = { _1 : 'a; _2 : 'a; _3 : 'a } | |
let inline RunTest<'a when 'a : equality> iterationCount createAssociativeMap (createKey:_->_->_->'a) = | |
System.GC.Collect () | |
System.GC.WaitForFullGCComplete () |> ignore | |
let data = [| | |
for a in 0..99 do | |
for b in 0..99 do | |
for c in 0..99 do | |
yield a,b,c |] | |
// shuffle | |
let r = System.Random (0) | |
for i = 0 to data.Length-1 do | |
let j = r.Next (i, data.Length) | |
let t = data.[i] | |
data.[i] <- data.[j] | |
data.[j] <- t | |
let keyValues = | |
data | |
|> Array.mapi (fun i k -> k, 0.5-(float i)/(float data.Length)) | |
|> Array.toSeq | |
let sw = System.Diagnostics.Stopwatch.StartNew () | |
let mapper = createAssociativeMap createKey keyValues | |
let creationTime = sw.ElapsedMilliseconds | |
let sw = System.Diagnostics.Stopwatch.StartNew () | |
let mutable checksum = 0. | |
for i = 0 to iterationCount do | |
let a, b, c = r.Next 100, r.Next 100, r.Next 100 | |
let key = createKey a b c | |
checksum <- checksum + (mapper key) | |
let accessTime= sw.ElapsedMilliseconds | |
checksum, creationTime, accessTime, (typeof<'a>.Name) | |
let inline RunNTrials<'a when 'a : equality> x = RunTest<'a> 1000000 x | |
let createDictionary create keyValues = | |
let d = System.Collections.Generic.Dictionary<_,_> () | |
keyValues | |
|> Seq.map (fun ((_1,_2,_3),value) -> create _1 _2 _3, value) | |
|> Seq.iter (fun (key,value) -> d.[key] <- value) | |
(fun key -> d.[key]) | |
let createDict create keyValues = | |
let d = | |
keyValues | |
|> Seq.map (fun ((_1,_2,_3),value) -> create _1 _2 _3, value) | |
|> dict | |
(fun key -> d.[key]) | |
let createMap create keyValues = | |
let d = | |
keyValues | |
|> Seq.map (fun ((_1,_2,_3),value) -> create _1 _2 _3, value) | |
|> Map.ofSeq | |
(fun key -> d.[key]) | |
let createCustomArray create keyValues = | |
let maxA = 1 + (keyValues |> Seq.map (fun ((a,_,_),_) -> a) |> Seq.max) | |
let maxB = 1 + (keyValues |> Seq.map (fun ((_,b,_),_) -> b) |> Seq.max) | |
let maxC = 1 + (keyValues |> Seq.map (fun ((_,_,c),_) -> c) |> Seq.max) | |
let createIndex a b c = a * maxB * maxC + b * maxC + c | |
let values : array<float> = Array.create (maxA * maxB * maxC) 0. | |
keyValues | |
|> Seq.iter (fun ((a,b,c),d) -> values.[createIndex a b c] <- d) | |
(fun (a,b,c) -> values.[a * maxB * maxC + b * maxC + c]) | |
let inline RunDictionary<'a when 'a : equality> = RunNTrials<'a> createDictionary | |
let inline RunDict<'a when 'a : equality> = RunNTrials<'a> createDict | |
let inline RunMap<'a when 'a : comparison> = RunNTrials<'a> createMap | |
let inline RunCustomArray x = RunNTrials<_> createCustomArray x | |
[<EntryPoint>] | |
let main argv = | |
let checksum, creation, access, typeName = | |
match argv with | |
| [| _; "KeyRecord" |] -> RunMap (fun a b c -> { KeyRecord._1=a; _2=b; _3=c }) | |
| [| _; "KeyGenericRecord" |] -> RunMap (fun a b c -> { KeyGenericRecord._1=a; _2=b; _3=c }) | |
| [| _; "KeyStruct" |] -> RunMap (fun a b c -> KeyStruct(a, b, c)) | |
| [| _; "KeyGenericStruct" |] -> RunMap (fun a b c -> KeyGenericStruct(a, b, c)) | |
| [| _; "tuple" |] -> RunMap (fun a b c -> (a, b, c)) | |
| [| _; "struct tuple" |] -> RunMap (fun a b c -> struct (a, b, c)) | |
| [| _; "int32" |] -> RunMap (fun a b c -> a <<< 22 ||| b <<< 11 ||| c) | |
| [| _; "int64" |] -> RunMap (fun a b c -> (int64 a) <<< 44 ||| (int64 b) <<< 22 ||| (int64 c)) | |
| _ -> failwith "unknown choice" | |
printfn "%s,%s,%s,%d,%d,%f" argv.[0] (if Environment.Is64BitProcess then "64-bit" else "32-bit") typeName creation access checksum | |
0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment