Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active December 24, 2015 15:49
Show Gist options
  • Save hodzanassredin/6823958 to your computer and use it in GitHub Desktop.
Save hodzanassredin/6823958 to your computer and use it in GitHub Desktop.
Buffer.BlockCopy vs unions
//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