KEMBAR78
Binary Reading in C# | PDF
https://github.com/neuecc/Messag
ePack-CSharp/
Int32 Read(byte[] bytes, int offset)
{
return (bytes[offset + 0] << 24)
| (bytes[offset + 1] << 16)
| (bytes[offset + 2] << 8)
| (bytes[offset + 3]);
}
Int32 Read(byte[] bytes, int offset)
{
return (bytes[offset + 0])
| (bytes[offset + 1] << 8)
| (bytes[offset + 2] << 16)
| (bytes[offset + 3] << 24);
}
unsafe int ReadInt32(byte[] bytes, int
offset)
{
fixed (byte* ptr = bytes)
{
return *(int*)(ptr + offset);
}
}
[StructLayout(LayoutKind.Explicit)]
internal struct Float32Bits
{
[FieldOffset(0)]
public float Value;
[FieldOffset(0)]
public Byte Byte0;
[FieldOffset(1)]
public Byte Byte1;
[FieldOffset(2)]
public Byte Byte2;
[FieldOffset(3)]
public Byte Byte3;
}
https://github.com/msgpack/msgpack/blob/master/spec.md
public MessagepackType ReadMessagePackType(byte[] bytes, int offset)
{
var code = bytes[offset];
if (0 <= code && code <= MessagePackRange.MaxFixPositiveInt)
{
return FixInt;
}
if (MessagePackRange.MinFixNegativeInt <= code)
{
return NegativeInt;
}
switch (code)
{
case Int8:
return Int8;
case Int16:
return Int16;
case Int32:
return Int32;
// 以下略
}
static readonly MessagePackType[] typeLookupTable = new MessagePackType[256];
static MessagePackCode()
{
for (int i = MinFixInt; i <= MaxFixInt; i++)
{
typeLookupTable[i] = MessagePackType.Integer;
}
for (int i = MinFixMap; i <= MaxFixMap; i++)
{
typeLookupTable[i] = MessagePackType.Map;
}
typeLookupTable[Nil] = MessagePackType.Nil;
typeLookupTable[False] = MessagePackType.Boolean;
typeLookupTable[True] = MessagePackType.Boolean;
typeLookupTable[Bin8] = MessagePackType.Binary;
typeLookupTable[Bin16] = MessagePackType.Binary;
// 以下略....
}
static readonly IMapHeaderDecoder[] mapHeaderDecoders = new IMapHeaderDecoder[MaxSize];
static readonly IArrayHeaderDecoder[] arrayHeaderDecoders = new IArrayHeaderDecoder[MaxSize];
static readonly IBooleanDecoder[] booleanDecoders = new IBooleanDecoder[MaxSize];
static readonly IByteDecoder[] byteDecoders = new IByteDecoder[MaxSize];
static readonly IBytesDecoder[] bytesDecoders = new IBytesDecoder[MaxSize];
static readonly ISByteDecoder[] sbyteDecoders = new ISByteDecoder[MaxSize];
static readonly ISingleDecoder[] singleDecoders = new ISingleDecoder[MaxSize];
static readonly IDoubleDecoder[] doubleDecoders = new IDoubleDecoder[MaxSize];
static readonly IInt16Decoder[] int16Decoders = new IInt16Decoder[MaxSize];
static readonly IInt32Decoder[] int32Decoders = new IInt32Decoder[MaxSize];
static readonly IInt64Decoder[] int64Decoders = new IInt64Decoder[MaxSize];
static readonly IUInt16Decoder[] uint16Decoders = new IUInt16Decoder[MaxSize];
static readonly IUInt32Decoder[] uint32Decoders = new IUInt32Decoder[MaxSize];
static readonly IUInt64Decoder[] uint64Decoders = new IUInt64Decoder[MaxSize];
static readonly IStringDecoder[] stringDecoders = new IStringDecoder[MaxSize];
static readonly IExtDecoder[] extDecoders = new IExtDecoder[MaxSize];
static readonly IExtHeaderDecoder[] extHeaderDecoders = new IExtHeaderDecoder[MaxSize];
static readonly IDateTimeDecoder[] dateTimeDecoders = new IDateTimeDecoder[MaxSize];
static readonly IReadNextDecoder[] readNextDecoders = new IReadNextDecoder[MaxSize];
static readonly IMapHeaderDecoder[] mapHeaderDecoders = new IMapHeaderDecoder[MaxSize];
static readonly IArrayHeaderDecoder[] arrayHeaderDecoders = new IArrayHeaderDecoder[MaxSize];
static readonly IBooleanDecoder[] booleanDecoders = new IBooleanDecoder[MaxSize];
static readonly IByteDecoder[] byteDecoders = new IByteDecoder[MaxSize];
static readonly IBytesDecoder[] bytesDecoders = new IBytesDecoder[MaxSize];
static readonly ISByteDecoder[] sbyteDecoders = new ISByteDecoder[MaxSize];
static readonly ISingleDecoder[] singleDecoders = new ISingleDecoder[MaxSize];
static readonly IDoubleDecoder[] doubleDecoders = new IDoubleDecoder[MaxSize];
static readonly IInt16Decoder[] int16Decoders = new IInt16Decoder[MaxSize];
static readonly IInt32Decoder[] int32Decoders = new IInt32Decoder[MaxSize];
static readonly IInt64Decoder[] int64Decoders = new IInt64Decoder[MaxSize];
static readonly IUInt16Decoder[] uint16Decoders = new IUInt16Decoder[MaxSize];
static readonly IUInt32Decoder[] uint32Decoders = new IUInt32Decoder[MaxSize];
static readonly IUInt64Decoder[] uint64Decoders = new IUInt64Decoder[MaxSize];
static readonly IStringDecoder[] stringDecoders = new IStringDecoder[MaxSize];
static readonly IExtDecoder[] extDecoders = new IExtDecoder[MaxSize];
static readonly IExtHeaderDecoder[] extHeaderDecoders = new IExtHeaderDecoder[MaxSize];
static readonly IDateTimeDecoder[] dateTimeDecoders = new IDateTimeDecoder[MaxSize];
static readonly IReadNextDecoder[] readNextDecoders = new IReadNextDecoder[MaxSize];
internal interface IInt32Decoder
{
Int32 Read(byte[] bytes, int offset, out int readSize);
}
デリゲートは楽
が、Fastestではない
void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
byte[] WriteVector3(Vector3[] collection)
{
var bytes = new byte[collection.Length * 12];
foreach (var item in collection)
{
WriteFloat(bytes, item.x);
WriteFloat(bytes, item.y);
WriteFloat(bytes, item.z);
}
return bytes;
}
public static unsafe void SimpleMemoryCopy(void* dest, void* src, int byteCount)
{
var pDest = (byte*)dest;
var pSrc = (byte*)src;
for (int i = 0; i < byteCount; i++)
{
*pDest = *pSrc;
pDest++;
pSrc++;
}
}
Vector3[]を一応Unityネイティブの
JsonUtilityの50倍高速にコピー可能
MessagePackの仕様内を逸脱しないよ
うに、Extension Formatを先頭識別子
に埋め込むことで互換性を保ちつつ
高速化

Binary Reading in C#

  • 2.
  • 3.
    Int32 Read(byte[] bytes,int offset) { return (bytes[offset + 0] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | (bytes[offset + 3]); } Int32 Read(byte[] bytes, int offset) { return (bytes[offset + 0]) | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16) | (bytes[offset + 3] << 24); } unsafe int ReadInt32(byte[] bytes, int offset) { fixed (byte* ptr = bytes) { return *(int*)(ptr + offset); } }
  • 4.
    [StructLayout(LayoutKind.Explicit)] internal struct Float32Bits { [FieldOffset(0)] publicfloat Value; [FieldOffset(0)] public Byte Byte0; [FieldOffset(1)] public Byte Byte1; [FieldOffset(2)] public Byte Byte2; [FieldOffset(3)] public Byte Byte3; }
  • 5.
  • 6.
    public MessagepackType ReadMessagePackType(byte[]bytes, int offset) { var code = bytes[offset]; if (0 <= code && code <= MessagePackRange.MaxFixPositiveInt) { return FixInt; } if (MessagePackRange.MinFixNegativeInt <= code) { return NegativeInt; } switch (code) { case Int8: return Int8; case Int16: return Int16; case Int32: return Int32; // 以下略 }
  • 7.
    static readonly MessagePackType[]typeLookupTable = new MessagePackType[256]; static MessagePackCode() { for (int i = MinFixInt; i <= MaxFixInt; i++) { typeLookupTable[i] = MessagePackType.Integer; } for (int i = MinFixMap; i <= MaxFixMap; i++) { typeLookupTable[i] = MessagePackType.Map; } typeLookupTable[Nil] = MessagePackType.Nil; typeLookupTable[False] = MessagePackType.Boolean; typeLookupTable[True] = MessagePackType.Boolean; typeLookupTable[Bin8] = MessagePackType.Binary; typeLookupTable[Bin16] = MessagePackType.Binary; // 以下略.... }
  • 8.
    static readonly IMapHeaderDecoder[]mapHeaderDecoders = new IMapHeaderDecoder[MaxSize]; static readonly IArrayHeaderDecoder[] arrayHeaderDecoders = new IArrayHeaderDecoder[MaxSize]; static readonly IBooleanDecoder[] booleanDecoders = new IBooleanDecoder[MaxSize]; static readonly IByteDecoder[] byteDecoders = new IByteDecoder[MaxSize]; static readonly IBytesDecoder[] bytesDecoders = new IBytesDecoder[MaxSize]; static readonly ISByteDecoder[] sbyteDecoders = new ISByteDecoder[MaxSize]; static readonly ISingleDecoder[] singleDecoders = new ISingleDecoder[MaxSize]; static readonly IDoubleDecoder[] doubleDecoders = new IDoubleDecoder[MaxSize]; static readonly IInt16Decoder[] int16Decoders = new IInt16Decoder[MaxSize]; static readonly IInt32Decoder[] int32Decoders = new IInt32Decoder[MaxSize]; static readonly IInt64Decoder[] int64Decoders = new IInt64Decoder[MaxSize]; static readonly IUInt16Decoder[] uint16Decoders = new IUInt16Decoder[MaxSize]; static readonly IUInt32Decoder[] uint32Decoders = new IUInt32Decoder[MaxSize]; static readonly IUInt64Decoder[] uint64Decoders = new IUInt64Decoder[MaxSize]; static readonly IStringDecoder[] stringDecoders = new IStringDecoder[MaxSize]; static readonly IExtDecoder[] extDecoders = new IExtDecoder[MaxSize]; static readonly IExtHeaderDecoder[] extHeaderDecoders = new IExtHeaderDecoder[MaxSize]; static readonly IDateTimeDecoder[] dateTimeDecoders = new IDateTimeDecoder[MaxSize]; static readonly IReadNextDecoder[] readNextDecoders = new IReadNextDecoder[MaxSize];
  • 9.
    static readonly IMapHeaderDecoder[]mapHeaderDecoders = new IMapHeaderDecoder[MaxSize]; static readonly IArrayHeaderDecoder[] arrayHeaderDecoders = new IArrayHeaderDecoder[MaxSize]; static readonly IBooleanDecoder[] booleanDecoders = new IBooleanDecoder[MaxSize]; static readonly IByteDecoder[] byteDecoders = new IByteDecoder[MaxSize]; static readonly IBytesDecoder[] bytesDecoders = new IBytesDecoder[MaxSize]; static readonly ISByteDecoder[] sbyteDecoders = new ISByteDecoder[MaxSize]; static readonly ISingleDecoder[] singleDecoders = new ISingleDecoder[MaxSize]; static readonly IDoubleDecoder[] doubleDecoders = new IDoubleDecoder[MaxSize]; static readonly IInt16Decoder[] int16Decoders = new IInt16Decoder[MaxSize]; static readonly IInt32Decoder[] int32Decoders = new IInt32Decoder[MaxSize]; static readonly IInt64Decoder[] int64Decoders = new IInt64Decoder[MaxSize]; static readonly IUInt16Decoder[] uint16Decoders = new IUInt16Decoder[MaxSize]; static readonly IUInt32Decoder[] uint32Decoders = new IUInt32Decoder[MaxSize]; static readonly IUInt64Decoder[] uint64Decoders = new IUInt64Decoder[MaxSize]; static readonly IStringDecoder[] stringDecoders = new IStringDecoder[MaxSize]; static readonly IExtDecoder[] extDecoders = new IExtDecoder[MaxSize]; static readonly IExtHeaderDecoder[] extHeaderDecoders = new IExtHeaderDecoder[MaxSize]; static readonly IDateTimeDecoder[] dateTimeDecoders = new IDateTimeDecoder[MaxSize]; static readonly IReadNextDecoder[] readNextDecoders = new IReadNextDecoder[MaxSize]; internal interface IInt32Decoder { Int32 Read(byte[] bytes, int offset, out int readSize); }
  • 10.
  • 11.
    void BlockCopy(Array src,int srcOffset, Array dst, int dstOffset, int count)
  • 12.
    byte[] WriteVector3(Vector3[] collection) { varbytes = new byte[collection.Length * 12]; foreach (var item in collection) { WriteFloat(bytes, item.x); WriteFloat(bytes, item.y); WriteFloat(bytes, item.z); } return bytes; }
  • 14.
    public static unsafevoid SimpleMemoryCopy(void* dest, void* src, int byteCount) { var pDest = (byte*)dest; var pSrc = (byte*)src; for (int i = 0; i < byteCount; i++) { *pDest = *pSrc; pDest++; pSrc++; } }
  • 15.