[Serializable]
[StructLayout(LayoutKind.Sequential)]
public class TestClass {
[MarshalAs(UnmanagedType.I4)]
public Int32 _int32;
[MarshalAs(UnmanagedType.U4)]
public UInt32 _uint32;
[MarshalAs(UnmanagedType.I8)]
public Int64 _int64;
[MarshalAs(UnmanagedType.U8)]
public UInt64 _uint64;
public void func_testMarshal(Random rnd){
for(int i=0; i<10000000; i++){
TestClass test = new TestClass(){
_int32 = rnd.Next(1, 65535),
_int64 = rnd.Next(1, 65535),
_uint32 = (uint)rnd.Next(1, 65535),
_uint64 = (ulong)rnd.Next(1, 65535)
};
byte[] b = MarshalUtils.StructureToByteArray(test);
// имитация бурной деятельности
b[0] = 1;
}
}
public static byte[] StructureToByteArray(object data){
var size = Marshal.SizeOf(data);
var bytes = new byte[size];
var ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(data, ptr, false);
Marshal.Copy(ptr, bytes, 0, size);
Marshal.FreeHGlobal(ptr);
return bytes;
}
for(int i=0; i<10000000; i++){
TestClass test = new TestClass(){
_int32 = rnd.Next(1, 65535),
_int64 = rnd.Next(1, 65535),
_uint32 = (uint)rnd.Next(1, 65535),
_uint64 = (ulong)rnd.Next(1, 65535)
};
byte[] b = test.Export1();
b[0] = 1;
}
public byte[] Export1(){
byte[] b = new byte[192];
byte[] b_int32 = BitConverter.GetBytes(_int32);
byte[] b_int64 = BitConverter.GetBytes(_int64);
byte[] b_uint32 = BitConverter.GetBytes(_uint32);
byte[] b_uint64 = BitConverter.GetBytes(_uint64);
Buffer.BlockCopy(b_int32, 0, b, 0, b_int32.Length);
Buffer.BlockCopy(b_int64, 0, b, b_int32.Length, b_int32.Length);
Buffer.BlockCopy(b_uint32, 0, b, b_int32.Length + b_int32.Length, b_uint32.Length);
Buffer.BlockCopy(b_uint64, 0, b, b_int32.Length + b_int32.Length + b_uint32.Length, b_uint64.Length);
return b;
}
struct CancellationRaised
{
Int64 MessageId,
Int64 CancellationTokenId,
}
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 1)]
public partial struct CancellationRaised
{
[FieldOffset(0)]
public Int64 MessageId;
[FieldOffset(8)]
public Int64 CancellationTokenId;
static CancellationRaised()
{
TypePacker<CancellationRaised>.Register<Serializer>();
}
public CancellationRaised(Int64 messageid, Int64 cancellationtokenid)
{
this.MessageId = messageid;
this.CancellationTokenId = cancellationtokenid;
}
public override int GetHashCode()
{
return unchecked
(
(this.MessageId == default(Int64) ? 0 : this.MessageId.GetHashCode()) +
(this.CancellationTokenId == default(Int64) ? 0 : this.CancellationTokenId.GetHashCode())
);
}
public override bool Equals(object value)
{
return value is CancellationRaised && this.Equals((CancellationRaised)value);
}
public bool Equals(CancellationRaised other)
{
return
(
object.Equals(this.MessageId, other.MessageId) &&
object.Equals(this.CancellationTokenId, other.CancellationTokenId)
);
}
public override string ToString()
{
return
(
"CancellationRaised, " +
"MessageId: " + this.MessageId + ", " +
"CancellationTokenId: " + this.CancellationTokenId
);
}
public sealed class Serializer : BlittableTypePacker<CancellationRaised>
{
public override int Write(ref CancellationRaised value, WriteBuffer writeBuffer)
{
writeBuffer.EnsureRange(16);
var buffer = writeBuffer.Buffer;
unsafe
{
fixed (byte* b = buffer)
*((CancellationRaised*)(b + writeBuffer.Offset)) = value;
}
writeBuffer.Offset += 16;
writeBuffer.BytesAvailable -= 16;
return 16;
}
public override int Read(out CancellationRaised value, ReadBuffer readBuffer)
{
readBuffer.EnsureRange(16);
var buffer = readBuffer.Buffer;
unsafe
{
fixed (byte* b = buffer)
value = *((CancellationRaised*)(b + readBuffer.Offset));
}
readBuffer.Offset += 16;
readBuffer.BytesAvailable -= 16;
return 16;
}
public override int Measure(ref CancellationRaised value)
{
return 16;
}
}
}
Size test: 1 card
With binary formatter: 896 bytes
Manual serializing: 62 bytes
Time test: 1 card, 100 000 times
Binary formatter serializing: 4,24 seconds
Manual serializing: 0,28 seconds
BinaryFormatter desrializing: 4,57 seconds
Manual desrializing: 0,169 seconds
Size test: 10 000 cards
With binary formatter: 640899 bytes
Manual serializing: 450062 bytes
Time test: 10 000 cards, 100 times
Binary formatter serializing: 4,713 seconds
Manual serializing: 0,527 seconds
BinaryFormatter desrializing: 4,519 seconds
Manual desrializing: 0,57 seconds