Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
Vectorize some Guid APIs (ctor, TryWriteBytes) (dotnet/coreclr#21336)
Browse files Browse the repository at this point in the history
* Optimize some Guid APIs

* get rid of WriteByteHelper

* use TryWrite instead of Write

* Optimize ctor `Guid(ReadOnlySpan<byte> b)` and remove `Equals` optimization (move to separate PR).

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
  • Loading branch information
EgorBo authored and Anipik committed Dec 4, 2018
1 parent 45c45fd commit 83d2289
Showing 1 changed file with 36 additions and 22 deletions.
58 changes: 36 additions & 22 deletions src/System.Private.CoreLib/shared/System/Guid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ public Guid(ReadOnlySpan<byte> b)
if ((uint)b.Length != 16)
throw new ArgumentException(SR.Format(SR.Arg_GuidArrayCtor, "16"), nameof(b));

if (BitConverter.IsLittleEndian)
{
this = MemoryMarshal.Read<Guid>(b);
return;
}

// slower path for BigEndian:
_k = b[15]; // hoist bounds checks
_a = b[3] << 24 | b[2] << 16 | b[1] << 8 | b[0];
_b = (short)(b[5] << 8 | b[4]);
_c = (short)(b[7] << 8 | b[6]);
Expand All @@ -61,7 +69,6 @@ public Guid(ReadOnlySpan<byte> b)
_h = b[12];
_i = b[13];
_j = b[14];
_k = b[15];
}

[CLSCompliant(false)]
Expand Down Expand Up @@ -93,14 +100,14 @@ public Guid(int a, short b, short c, byte[] d)
_a = a;
_b = b;
_c = c;
_k = d[7]; // hoist bounds checks
_d = d[0];
_e = d[1];
_f = d[2];
_g = d[3];
_h = d[4];
_i = d[5];
_j = d[6];
_k = d[7];
}

// Creates a new GUID initialized to the value represented by the
Expand Down Expand Up @@ -768,9 +775,34 @@ private static bool IsHexPrefix(ReadOnlySpan<char> str, int i) =>
str[i] == '0' &&
(str[i + 1] | 0x20) == 'x';

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void WriteByteHelper(Span<byte> destination)
// Returns an unsigned byte array containing the GUID.
public byte[] ToByteArray()
{
var g = new byte[16];
if (BitConverter.IsLittleEndian)
{
MemoryMarshal.TryWrite<Guid>(g, ref this);
}
else
{
TryWriteBytes(g);
}
return g;
}

// Returns whether bytes are sucessfully written to given span.
public bool TryWriteBytes(Span<byte> destination)
{
if (BitConverter.IsLittleEndian)
{
return MemoryMarshal.TryWrite(destination, ref this);
}

// slower path for BigEndian
if (destination.Length < 16)
return false;

destination[15] = _k; // hoist bounds checks
destination[0] = (byte)(_a);
destination[1] = (byte)(_a >> 8);
destination[2] = (byte)(_a >> 16);
Expand All @@ -786,24 +818,6 @@ private void WriteByteHelper(Span<byte> destination)
destination[12] = _h;
destination[13] = _i;
destination[14] = _j;
destination[15] = _k;
}

// Returns an unsigned byte array containing the GUID.
public byte[] ToByteArray()
{
var g = new byte[16];
WriteByteHelper(g);
return g;
}

// Returns whether bytes are sucessfully written to given span.
public bool TryWriteBytes(Span<byte> destination)
{
if (destination.Length < 16)
return false;

WriteByteHelper(destination);
return true;
}

Expand Down

0 comments on commit 83d2289

Please sign in to comment.