Skip to content

Commit

Permalink
SIMD optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
TitleHHHH authored and TitleHHHH committed Sep 20, 2024
1 parent 1201b0c commit 4a77dd1
Showing 1 changed file with 111 additions and 0 deletions.
111 changes: 111 additions & 0 deletions src/McProtoNet/McProtoNet.Serialization/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System.Buffers.Binary;
using System.Runtime.InteropServices;

namespace McProtoNet.Serialization;

public static class ReadArraysSIMDExtensions
{
public static int[] ReadArrayInt32BigEndian(this MinecraftPrimitiveReaderSlim reader, int length)
{
if (reader.RemainingCount < length)
{
throw new InsufficientMemoryException();
}

ReadOnlySpan<byte> bytes = reader.Read(sizeof(int) * length);
ReadOnlySpan<int> ints = MemoryMarshal.Cast<byte, int>(bytes);
if (BitConverter.IsLittleEndian)
{
int[] result = new int[length];
BinaryPrimitives.ReverseEndianness(ints, result);
return result;
}
return ints.ToArray();
}
public static long[] ReadArrayInt64BigEndian(this MinecraftPrimitiveReaderSlim reader, int length)
{
if (reader.RemainingCount < length)
{
throw new InsufficientMemoryException();
}

ReadOnlySpan<byte> bytes = reader.Read(sizeof(long) * length);
ReadOnlySpan<long> ints = MemoryMarshal.Cast<byte, long>(bytes);
if (BitConverter.IsLittleEndian)
{
long[] result = new long[length];
BinaryPrimitives.ReverseEndianness(ints, result);
return result;
}
return ints.ToArray();
}
public static short[] ReadArrayInt16BigEndian(this MinecraftPrimitiveReaderSlim reader, int length)
{
if (reader.RemainingCount < length)
{
throw new InsufficientMemoryException();
}

ReadOnlySpan<byte> bytes = reader.Read(sizeof(short) * length);
ReadOnlySpan<short> ints = MemoryMarshal.Cast<byte, short>(bytes);
if (BitConverter.IsLittleEndian)
{
short[] result = new short[length];
BinaryPrimitives.ReverseEndianness(ints, result);
return result;
}
return ints.ToArray();
}
public static ushort[] ReadArrayUnsignedInt16BigEndian(this MinecraftPrimitiveReaderSlim reader, int length)
{
if (reader.RemainingCount < length)
{
throw new InsufficientMemoryException();
}

ReadOnlySpan<byte> bytes = reader.Read(sizeof(ushort) * length);
ReadOnlySpan<ushort> ints = MemoryMarshal.Cast<byte, ushort>(bytes);
if (BitConverter.IsLittleEndian)
{
ushort[] result = new ushort[length];
BinaryPrimitives.ReverseEndianness(ints, result);
return result;
}
return ints.ToArray();
}
public static uint[] ReadArrayUnsignedInt32BigEndian(this MinecraftPrimitiveReaderSlim reader, int length)
{
if (reader.RemainingCount < length)
{
throw new InsufficientMemoryException();
}

ReadOnlySpan<byte> bytes = reader.Read(sizeof(uint) * length);
ReadOnlySpan<uint> ints = MemoryMarshal.Cast<byte, uint>(bytes);
if (BitConverter.IsLittleEndian)
{
uint[] result = new uint[length];
BinaryPrimitives.ReverseEndianness(ints, result);
return result;
}
return ints.ToArray();
}
public static ulong[] ReadArrayUnsignedInt64BigEndian(this MinecraftPrimitiveReaderSlim reader, int length)
{
if (reader.RemainingCount < length)
{
throw new InsufficientMemoryException();
}

ReadOnlySpan<byte> bytes = reader.Read(sizeof(ulong) * length);
ReadOnlySpan<ulong> ints = MemoryMarshal.Cast<byte, ulong>(bytes);
if (BitConverter.IsLittleEndian)
{
ulong[] result = new ulong[length];
BinaryPrimitives.ReverseEndianness(ints, result);
return result;
}
return ints.ToArray();
}

}

0 comments on commit 4a77dd1

Please sign in to comment.