Created
October 4, 2013 09:09
-
-
Save hodzanassredin/6823148 to your computer and use it in GitHub Desktop.
Checking perf and memory usage disc unions vs custom struct with tag and bitconverter
This file contains hidden or 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
| //Results on my machine | |
| //U1 Elapsed Time: 2541 Consumed memory: 81313836 | |
| //U2 Elapsed Time: 1835 Consumed memory: 58804716 | |
| //U1 Elapsed Time: 2144 Consumed memory: 80130316 | |
| //U2 Elapsed Time: 1682 Consumed memory: 57352372 | |
| //U1 Elapsed Time: 2109 Consumed memory: 81020952 | |
| //U2 Elapsed Time: 1672 Consumed memory: 58831224 | |
| open System | |
| type U1 = | |
| | F of float32 | |
| | C of char | |
| | I of int | |
| type U2Tag = | |
| | F = 0uy | |
| | C = 1uy | |
| | I = 2uy | |
| type U2 = | |
| struct | |
| val tag: U2Tag | |
| val b0: byte | |
| val b1: byte | |
| val b2: byte | |
| val b3: byte | |
| new(x: float32) = | |
| let arr = BitConverter.GetBytes(x) | |
| { | |
| tag = U2Tag.F; | |
| b0 = arr.[0]; | |
| b1 = arr.[1]; | |
| b2 = arr.[2]; | |
| b3 = arr.[3]; | |
| } | |
| new(x: int) = | |
| let arr = BitConverter.GetBytes(x) | |
| { | |
| tag = U2Tag.I; | |
| b0 = arr.[0]; | |
| b1 = arr.[1]; | |
| b2 = arr.[2]; | |
| b3 = arr.[3]; | |
| } | |
| new(x: char) = | |
| let arr = BitConverter.GetBytes(x) | |
| { | |
| tag = U2Tag.C; | |
| b0 = arr.[0]; | |
| b1 = arr.[1]; | |
| b2 = 0uy; | |
| b3 = 0uy; | |
| } | |
| member this.char = | |
| if this.tag = U2Tag.C | |
| then BitConverter.ToChar([|this.b0;this.b1|], 0) | |
| else failwith "it is not a char" | |
| member this.int = | |
| if this.tag = U2Tag.I | |
| then BitConverter.ToInt32([|this.b0;this.b1;this.b2;this.b3|], 0) | |
| else failwith "it is not an int" | |
| member this.float32 = | |
| if this.tag = U2Tag.F | |
| then BitConverter.ToSingle([|this.b0;this.b1;this.b2;this.b3|], 0) | |
| else failwith "it is not a float" | |
| end | |
| let duration str f = | |
| let timer = new System.Diagnostics.Stopwatch() | |
| let memory = GC.GetTotalMemory(true) | |
| timer.Start() | |
| let returnValue = f() | |
| timer.Stop() | |
| let memoryUsage = GC.GetTotalMemory(false) - memory | |
| printfn "%s Elapsed Time: %i Consumed memory: %d" str timer.ElapsedMilliseconds memoryUsage | |
| returnValue | |
| let max = 1000000 | |
| let test data = | |
| let arr = Array.zeroCreate (max + 1) | |
| for idx in 0..max do | |
| let c,i,f = data(idx) | |
| arr.[idx] <- [|c,i,f|] | |
| arr | |
| [<EntryPoint>] | |
| let main argv = | |
| let u1data i = (C('a'), I(i), F(float32 i)) | |
| let testu1() = test u1data | |
| let u2data (i:int) = (new U2('a'), new U2(i), new U2(float32 i)) | |
| let testu2() = test u2data | |
| for i in 0..10 do | |
| duration "U1" testu1 |> ignore | |
| duration "U2" testu2 |> ignore | |
| printfn "%A" argv | |
| 0 // return an integer exit code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
How about this code (simpler, appears to have the same perf, fewer allocations for int/char cases)