Last active
December 24, 2015 15:49
-
-
Save hodzanassredin/6823958 to your computer and use it in GitHub Desktop.
Buffer.BlockCopy vs unions
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: 2285 Consumed memory: 81313268 | |
| //U2 Elapsed Time: 5729 Consumed memory: 60775624 | |
| //U1 Elapsed Time: 2141 Consumed memory: 80048624 | |
| //U2 Elapsed Time: 6011 Consumed memory: 57525248 | |
| //U1 Elapsed Time: 2208 Consumed memory: 81011948 | |
| //U2 Elapsed Time: 5653 Consumed memory: 58437492 | |
| 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 v = [|0uy; 0uy; 0uy; 0uy |] | |
| Buffer.BlockCopy([|x|], 0 , v, 0, 4) | |
| { | |
| tag = U2Tag.F; | |
| b0 = v.[0]; | |
| b1 = v.[1]; | |
| b2 = v.[2]; | |
| b3 = v.[3]; | |
| } | |
| new(x: int) = | |
| let v = [|0uy; 0uy; 0uy; 0uy |] | |
| Buffer.BlockCopy([|x|], 0 , v, 0, 4) | |
| { | |
| tag = U2Tag.I; | |
| b0 = v.[0]; | |
| b1 = v.[1]; | |
| b2 = v.[2]; | |
| b3 = v.[3]; | |
| } | |
| new(x: char) = | |
| let v = [|0uy; 0uy; |] | |
| Buffer.BlockCopy([|x|], 0 , v, 0, 2) | |
| { | |
| tag = U2Tag.I; | |
| b0 = v.[0]; | |
| b1 = v.[1]; | |
| b2 = 0uy; | |
| b3 = 0uy; | |
| } | |
| member this.char : char = | |
| if this.tag = U2Tag.C | |
| then let res = Array.zeroCreate 1 | |
| Buffer.BlockCopy([|this.b0; this.b1|], 0 , res, 0, 2) | |
| res.[0] | |
| else failwith "it is not a char" | |
| member this.int : int = | |
| if this.tag = U2Tag.I | |
| then let res = Array.zeroCreate 1 | |
| Buffer.BlockCopy([|this.b0; this.b1;this.b2; this.b3|], 0 , res, 0, 4) | |
| res.[0] | |
| else failwith "it is not an int" | |
| member this.float32 : float32= | |
| if this.tag = U2Tag.F | |
| then let res = Array.zeroCreate 1 | |
| Buffer.BlockCopy([|this.b0; this.b1;this.b2; this.b3|], 0 , res, 0, 4) | |
| res.[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 | |
| 0 // return an integer exit code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment