It provide an union type struct, for strongly typed c# language.
Use Memory mask
to make struct has 16(maximum primary type bytes)+1(type store)
bytes, it can be store primary types.
Object store use GCHandle
to pin memory.
samples/UnionType.Sample
using System;
using UnionType;
internal class Program
{
static void Main()
{
UnionValue a = 123;
int b = a;//123
}
}
using System;
using UnionType;
internal class Program
{
unsafe static void Main()
{
UnionValue a = 123;
Console.WriteLine(*a.ToPointer<int>());//Print 123
}
}
using System;
using UnionType;
internal class Program
{
static void Main()
{
var uv = (UnionValue)123;
Inc(ref uv);
Console.WriteLine(uv.@int);//Print 124
}
private static void Inc(ref UnionValue value)
{
value.@int++;
}
}
void
(Empty)byte
sbyte
bool
char
short
ushort
int
uint
long
ulong
float
(Single)double
decimal
object
DBNull
DateTime
String
TimeSpan
(Additional types)Guid
(Additional types)IntPtr
(Additional types)
Performace is alloc decimal benchmark
using System;
using UnionType;
internal class Program
{
static void Main()
{
var uv = UnionValue.FromAsDecimal(123);
Console.WriteLine(uv.@decimal);//123
}
}
- ICloneable
- IComparable
- IConvertible
- IFormattable
using System;
using System.Runtime.CompilerServices;
using UnionType;
internal class Program
{
static void Main()
{
Console.WriteLine(Unsafe.SizeOf<UnionValue>());//In .NET7.0 print 24, other print 17
}
}
using System;
using UnionType;
internal class Program
{
static void Main()
{
UnionValue a = 123;
UnionValue b = 456;
var result = a + b;
Console.WriteLine(result.ToString());//579
}
}
Supports
+
-
*
/
%
Integer will become long, floating point will become decimal
using System;
using UnionType;
internal class Program
{
static void Main()
{
UnionValue a = 123;
var b = 456;
Console.WriteLine(a > b);//False
Console.WriteLine(a < b);//True
}
}
Supports
>
>=
<
<=
==
It will check type!=
It will check type
using System;
using UnionType;
internal class Program
{
static void Main()
{
var obj = new Program();
var uv = new UnionValue { Object = obj };
Console.WriteLine(uv.TypeNameString);//Program, rsa2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Console.WriteLine(uv.Object);//Program
}
}
using System;
using UnionType;
internal class Program
{
static void Main()
{
var uv = UnionValue.FromAsDecimal(123);
Console.WriteLine(uv.Box());//123
}
}
using System;
using UnionType;
internal class Program
{
static void Main()
{
var uv = UnionValue.FromObject(123);//Fast
Console.WriteLine(uv.Box());//123
uv = UnionValue.FromObject((object)123);
Console.WriteLine(uv.Box());//123
}
}
I use raw point copy!
UnionType/src/UnionType/UnionValueCreator.cs
Line 108 in eff150c
In serialize case.(Can see UnionValueToBytesHelperTest.cs
)
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.2364)
Intel Core i5-9400F CPU 2.90GHz (Coffee Lake), 1 CPU, 6 logical and 6 physical cores
.NET SDK=7.0.100
[Host] : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
Method | Count | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio |
---|---|---|---|---|---|---|---|---|
Decimal | 500 | 136.3 ns | 0.37 ns | 0.33 ns | 1.00 | 0.00 | - | NA |
Union | 500 | 136.5 ns | 0.47 ns | 0.42 ns | 1.00 | 0.00 | - | NA |
Box | 500 | 136.5 ns | 0.66 ns | 0.62 ns | 1.00 | 0.00 | - | NA |
BigInteger | 500 | 912.7 ns | 3.84 ns | 3.59 ns | 6.70 | 0.03 | - | NA |
Decimal | 5000000 | 1,290,235.7 ns | 2,928.91 ns | 2,596.40 ns | 1.00 | 0.00 | - | NA |
Union | 5000000 | 1,291,152.6 ns | 4,300.97 ns | 3,812.70 ns | 1.00 | 0.00 | 1 B | NA |
Box | 5000000 | 1,291,088.1 ns | 3,581.48 ns | 2,990.70 ns | 1.00 | 0.00 | 1 B | NA |
BigInteger | 5000000 | 9,026,300.8 ns | 10,061.51 ns | 8,919.27 ns | 7.00 | 0.01 | 8 B | NA |