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)bytesbyteboolcharshortushortintuintlongulongfloat(Single)doubledecimalobjectDBNullDateTimeStringTimeSpan(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 |