Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Aug 2, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
171a23a
Optimizing some int32 parsers and clean up
ahsonkhan Jun 16, 2017
befd080
wip - adding tests and fixing impl bugs
ahsonkhan Jun 19, 2017
174e2f8
WIP - new implementation and tests to compare with previous
ahsonkhan Jun 20, 2017
568e736
WIP - fixing non-invariant parser bugs and adding tests
ahsonkhan Jun 21, 2017
c8f775d
Cleaning up functional and performance tests and removing old code.
ahsonkhan Jun 21, 2017
e5c0cac
Removing unnecessary using directive
ahsonkhan Jun 21, 2017
09cd24c
Addressing PR comments and adding more tests.
ahsonkhan Jun 23, 2017
0e0ff41
Merge branch 'master' of https://github.com/dotnet/corefxlab into Opt…
ahsonkhan Jun 23, 2017
67183fe
Addressing PR comments and adding loop unrolling.
ahsonkhan Jun 23, 2017
ba83ad1
Merge branch 'master' of https://github.com/dotnet/corefxlab into Opt…
ahsonkhan Jun 23, 2017
91a6191
Fixing issues missed after merge
ahsonkhan Jun 23, 2017
65b8221
Fixing non-invariant int32 parser
ahsonkhan Jun 24, 2017
cfa230f
Addressing PR comment, removing unused DangerousGetPinnableReference
ahsonkhan Jun 24, 2017
86f4969
Cleanup and updating test helpers
ahsonkhan Jun 24, 2017
e89a809
Patch to dotnet install scripts for downloading via new blob URL. (#1…
shiftylogic Jun 26, 2017
f4c8e83
Removing text.Length cache and changing to unsigned comparison
ahsonkhan Jun 26, 2017
b7ce275
Adding comment and removing unnecessary math operations using 0 (D0)
ahsonkhan Jun 26, 2017
1a329f4
Api brotli changes (#1621)
Jun 27, 2017
b7800f8
Merge branch 'master' into OptimizingParser
ahsonkhan Jun 27, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Optimizing some int32 parsers and clean up
  • Loading branch information
ahsonkhan committed Jun 16, 2017
commit 171a23af17f95991851cd0a33e12acc0922a0781
192 changes: 40 additions & 152 deletions src/System.Text.Primitives/System/Text/Parsing/InvariantSigned.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
// NOTE: This file is generated via a T4 template. Please do not edit this file directly. Any changes should be made
// in InvariantSigned.tt.


using System.Runtime.CompilerServices;

namespace System.Text
{
public static partial class PrimitiveParser
Expand Down Expand Up @@ -899,179 +902,64 @@ public unsafe static bool TryParseInt32(byte* text, int length, out int value, o

public static bool TryParseInt32(ReadOnlySpan<byte> text, out int value)
{
if (text.Length < 1)
{
value = default(int);
return false;
}

int indexOfFirstDigit = 0;
int sign = 1;
if (text[0] == '-')
{
indexOfFirstDigit = 1;
sign = -1;
}
else if (text[0] == '+')
{
indexOfFirstDigit = 1;
}

int overflowLength = Int32OverflowLength + indexOfFirstDigit;

// Parse the first digit separately. If invalid here, we need to return false.
int firstDigit = text[indexOfFirstDigit] - 48; // '0'
if (firstDigit < 0 || firstDigit > 9)
{
value = default(int);
return false;
}
int parsedValue = firstDigit;

if (text.Length < overflowLength)
{
// Length is less than Int32OverflowLength; overflow is not possible
for (int index = indexOfFirstDigit + 1; index < text.Length; index++)
{
int nextDigit = text[index] - 48; // '0'
if (nextDigit < 0 || nextDigit > 9)
{
value = parsedValue * sign;
return true;
}
parsedValue = parsedValue * 10 + nextDigit;
}
}
else
{
// Length is greater than Int32OverflowLength; overflow is only possible after Int32OverflowLength
// digits. There may be no overflow after Int32OverflowLength if there are leading zeroes.
for (int index = indexOfFirstDigit + 1; index < overflowLength - 1; index++)
{
int nextDigit = text[index] - 48; // '0'
if (nextDigit < 0 || nextDigit > 9)
{
value = parsedValue * sign;
return true;
}
parsedValue = parsedValue * 10 + nextDigit;
}
for (int index = overflowLength - 1; index < text.Length; index++)
{
int nextDigit = text[index] - 48; // '0'
if (nextDigit < 0 || nextDigit > 9)
{
value = parsedValue * sign;
return true;
}
// If parsedValue > (int.MaxValue / 10), any more appended digits will cause overflow.
// if parsedValue == (int.MaxValue / 10), any nextDigit greater than 7 or 8 (depending on sign) implies overflow.
bool positive = sign > 0;
bool nextDigitTooLarge = nextDigit > 8 || (positive && nextDigit > 7);
if (parsedValue > int.MaxValue / 10 || parsedValue == int.MaxValue / 10 && nextDigitTooLarge)
{
value = default(int);
return false;
}
parsedValue = parsedValue * 10 + nextDigit;
}
}

value = parsedValue * sign;
return true;
return TryParseInt32(text, out value, out int bytesConsumed);
}

public static bool TryParseInt32(ReadOnlySpan<byte> text, out int value, out int bytesConsumed)
{
if (text.Length < 1)
{
bytesConsumed = 0;
value = default(int);
return false;
}
ref byte textByte = ref text.DangerousGetPinnableReference();

int indexOfFirstDigit = 0;
int sign = 1;
if (text[0] == '-')
int index = 0;
if (textByte == '-')
{
indexOfFirstDigit = 1;
sign = -1;
index++;
}
else if (text[0] == '+')
else if (textByte == '+')
{
indexOfFirstDigit = 1;
index++;
}

int overflowLength = Int32OverflowLength + indexOfFirstDigit;
int textLength = text.Length;
int overflowLength = Int32OverflowLength + index;
if (textLength > overflowLength) textLength = overflowLength;

// Parse the first digit separately. If invalid here, we need to return false.
int firstDigit = text[indexOfFirstDigit] - 48; // '0'
if (firstDigit < 0 || firstDigit > 9)
int answer = 0;
int num = 0;
bool containsDigitsAsPrefix = false;
while (index < textLength - 1)
{
bytesConsumed = 0;
value = default(int);
return false;
}
int parsedValue = firstDigit;

if (text.Length < overflowLength)
{
// Length is less than Int32OverflowLength; overflow is not possible
for (int index = indexOfFirstDigit + 1; index < text.Length; index++)
num = Unsafe.Add(ref textByte, index) - 48; // '0'
if (!IsDigit(num))
{
int nextDigit = text[index] - 48; // '0'
if (nextDigit < 0 || nextDigit > 9)
{
bytesConsumed = index;
value = parsedValue * sign;
return true;
}
parsedValue = parsedValue * 10 + nextDigit;
goto Done;
}
answer = answer * 10 + num;
containsDigitsAsPrefix = true;
index++;
}
else

num = Unsafe.Add(ref textByte, textLength - 1) - 48; // '0'
if (IsDigit(num))
{
// Length is greater than Int32OverflowLength; overflow is only possible after Int32OverflowLength
// digits. There may be no overflow after Int32OverflowLength if there are leading zeroes.
for (int index = indexOfFirstDigit + 1; index < overflowLength - 1; index++)
{
int nextDigit = text[index] - 48; // '0'
if (nextDigit < 0 || nextDigit > 9)
{
bytesConsumed = index;
value = parsedValue * sign;
return true;
}
parsedValue = parsedValue * 10 + nextDigit;
}
for (int index = overflowLength - 1; index < text.Length; index++)
{
int nextDigit = text[index] - 48; // '0'
if (nextDigit < 0 || nextDigit > 9)
{
bytesConsumed = index;
value = parsedValue * sign;
return true;
}
// If parsedValue > (int.MaxValue / 10), any more appended digits will cause overflow.
// if parsedValue == (int.MaxValue / 10), any nextDigit greater than 7 or 8 (depending on sign) implies overflow.
bool positive = sign > 0;
bool nextDigitTooLarge = nextDigit > 8 || (positive && nextDigit > 7);
if (parsedValue > int.MaxValue / 10 || parsedValue == int.MaxValue / 10 && nextDigitTooLarge)
{
bytesConsumed = 0;
value = default(int);
return false;
}
parsedValue = parsedValue * 10 + nextDigit;
}
if (WillOverFlow(answer, num, sign)) goto FalseExit;
containsDigitsAsPrefix = true;
answer = answer * 10 + num;
index++;
}

bytesConsumed = text.Length;
value = parsedValue * sign;
Done:
if (!containsDigitsAsPrefix) goto FalseExit;
bytesConsumed = index;
value = answer * sign;
return true;
}

FalseExit:
bytesConsumed = 0;
value = default;
return false;
}
#endregion

#region Int64
Expand Down Expand Up @@ -2844,4 +2732,4 @@ public static bool TryParseInt64(ReadOnlySpan<char> text, out long value, out in

}
}
}
}
Loading