Skip to content

Commit

Permalink
Eliminate allocation in parse method by removing foreach loop (enumea…
Browse files Browse the repository at this point in the history
…tor)
  • Loading branch information
Troy Willmot committed Jul 30, 2017
1 parent 2c2e42d commit 948cb0c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 25 deletions.
2 changes: 0 additions & 2 deletions src/Xid.Net.Tests/Xid_New_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ public void Xid_New_GeneratesUniqueXids()
public void Xid_New_GeneratesUniqueXids_Threaded()
{
int maxIterations = 10000000;
if (IntPtr.Size > 4)
maxIterations = 40000000; //Moa tests on 64 bit! (32 bit runs out of contiguous memory for dictionary)

int threadCount = Math.Max(2, Environment.ProcessorCount);
int step = maxIterations / threadCount;
Expand Down
38 changes: 15 additions & 23 deletions src/Xid.Shared/Xid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,10 @@ public static bool TryParse(string encodedXid, out Xid xid)

private static bool ContainsOnlyValidXidChars(string encodedXid)
{
foreach (char c in encodedXid)
Char c;
for (int i = 0; i < encodedXid.Length; i++)
{
c = encodedXid[i];
if (c < '0' || (c > '9' && c < 'a') || c > 'v')
{
return false;
Expand All @@ -167,28 +169,18 @@ private static byte[] InternalParse(string xidStr)
{
byte[] retVal = new byte[Xid.Length];

////TODO: This is shitty when called from tryparse.
////One of the main reasons for tryparse is to avoid the overhead
////of exceptions. Can we do better?
//try
//{
retVal[0] = (byte)(DecodeMap[xidStr[0]] << 3 | DecodeMap[xidStr[1]] >> 2);
retVal[1] = (byte)(DecodeMap[xidStr[1]] << 6 | DecodeMap[xidStr[2]] << 1 | DecodeMap[xidStr[3]] >> 4);
retVal[2] = (byte)(DecodeMap[xidStr[3]] << 4 | DecodeMap[xidStr[4]] >> 1);
retVal[3] = (byte)(DecodeMap[xidStr[4]] << 7 | DecodeMap[xidStr[5]] << 2 | DecodeMap[xidStr[6]] >> 3);
retVal[4] = (byte)(DecodeMap[xidStr[6]] << 5 | DecodeMap[xidStr[7]]);
retVal[5] = (byte)(DecodeMap[xidStr[8]] << 3 | DecodeMap[xidStr[9]] >> 2);
retVal[6] = (byte)(DecodeMap[xidStr[9]] << 6 | DecodeMap[xidStr[10]] << 1 | DecodeMap[xidStr[11]] >> 4);
retVal[7] = (byte)(DecodeMap[xidStr[11]] << 4 | DecodeMap[xidStr[12]] >> 1);
retVal[8] = (byte)(DecodeMap[xidStr[12]] << 7 | DecodeMap[xidStr[13]] << 2 | DecodeMap[xidStr[14]] >> 3);
retVal[9] = (byte)(DecodeMap[xidStr[14]] << 5 | DecodeMap[xidStr[15]]);
retVal[10] = (byte)(DecodeMap[xidStr[16]] << 3 | DecodeMap[xidStr[17]] >> 2);
retVal[11] = (byte)(DecodeMap[xidStr[17]] << 6 | DecodeMap[xidStr[18]] << 1 | DecodeMap[xidStr[19]] >> 4);
//}
//catch (IndexOutOfRangeException)
//{
// return null;
//}
retVal[0] = (byte)(DecodeMap[xidStr[0]] << 3 | DecodeMap[xidStr[1]] >> 2);
retVal[1] = (byte)(DecodeMap[xidStr[1]] << 6 | DecodeMap[xidStr[2]] << 1 | DecodeMap[xidStr[3]] >> 4);
retVal[2] = (byte)(DecodeMap[xidStr[3]] << 4 | DecodeMap[xidStr[4]] >> 1);
retVal[3] = (byte)(DecodeMap[xidStr[4]] << 7 | DecodeMap[xidStr[5]] << 2 | DecodeMap[xidStr[6]] >> 3);
retVal[4] = (byte)(DecodeMap[xidStr[6]] << 5 | DecodeMap[xidStr[7]]);
retVal[5] = (byte)(DecodeMap[xidStr[8]] << 3 | DecodeMap[xidStr[9]] >> 2);
retVal[6] = (byte)(DecodeMap[xidStr[9]] << 6 | DecodeMap[xidStr[10]] << 1 | DecodeMap[xidStr[11]] >> 4);
retVal[7] = (byte)(DecodeMap[xidStr[11]] << 4 | DecodeMap[xidStr[12]] >> 1);
retVal[8] = (byte)(DecodeMap[xidStr[12]] << 7 | DecodeMap[xidStr[13]] << 2 | DecodeMap[xidStr[14]] >> 3);
retVal[9] = (byte)(DecodeMap[xidStr[14]] << 5 | DecodeMap[xidStr[15]]);
retVal[10] = (byte)(DecodeMap[xidStr[16]] << 3 | DecodeMap[xidStr[17]] >> 2);
retVal[11] = (byte)(DecodeMap[xidStr[17]] << 6 | DecodeMap[xidStr[18]] << 1 | DecodeMap[xidStr[19]] >> 4);

return retVal;
}
Expand Down

0 comments on commit 948cb0c

Please sign in to comment.