private const char CharNegative = '-';
private const int possibleMaxLength = 10;
private const int possibleMaxNegativeLength = 11;
private static string comparePositive = int.MaxValue.ToString();
private static string compareNegative =int.MinValue.ToString();
public static bool FastTryParseIntOld2FastTryParseInt(string input, out int result)
{
result = 0;
if (string.IsNullOrWhiteSpace(input)) { return false; }
int length = input.Length;
bool isNegative = false;
int currentIndex = 0;
if (input[0] == CharNegative)
{
if (length > possibleMaxNegativeLength) { return false; }
isNegative = true;
++currentIndex;
}
int maxLength = isNegative ? possibleMaxNegativeLength : possibleMaxLength;
if (length > maxLength)
{
return false;
}
else if (length < maxLength)
{
char nextChar;
while (currentIndex < length)
{
nextChar = input[currentIndex++];
if (nextChar < '0' || nextChar > '9')
{
result = 0;
return false;
}
result = result * 10 + (nextChar - '0');
}
}
else
{
bool needsToBeCompared = true;
string valueToCompare = isNegative ? compareNegative : comparePositive;
char nextChar;
char compareChar;
while (currentIndex < maxLength)
{
nextChar = input[currentIndex];
compareChar = valueToCompare[currentIndex];
if (nextChar < '0' || nextChar > '9' || (needsToBeCompared && compareChar < nextChar))
{
result = 0;
return false;
}
if (needsToBeCompared)
{
needsToBeCompared = compareChar == nextChar;
}
result = result * 10 + (nextChar - '0');
currentIndex++;
}
}
if (isNegative) { result = -result; }
return true;
}
private static Random random = new Random();
private static IEnumerable<string> GenerateRandomInput(int iterations)
{
if (iterations == 0) yield break;
for (int i = 0; i < iterations; i++)
{
if (i % 2 == 0)
{
yield return LongRandom((long)int.MinValue, ((long)int.MaxValue)).ToString();
}
else if (i % 3 == 0)
{
yield return LongRandom((long)int.MaxValue, ((long)int.MaxValue + 10000)).ToString();
}
else
{
yield return LongRandom(long.MinValue, long.MaxValue).ToString().Insert(3, "a");
}
}
}
private static long LongRandom(long min, long max)
{
byte[] buf = new byte[8];
random.NextBytes(buf);
long longRand = BitConverter.ToInt64(buf, 0);
return (Math.Abs(longRand % (max - min)) + min);
}
Edit
Since you don't bother about special cases like null being passed to the method and performance is your target, I have changed it like so
public static bool FastTryParseInt(string input, out int result)
{
result = 0;
int length = input.Length;
if (length == 0) { return false; }
bool isNegative = false;
int currentIndex = 0;
if (input[0] == CharNegative)
{
if (length > possibleMaxNegativeLength) { return false; }
isNegative = true;
++currentIndex;
}
int maxLength = isNegative ? possibleMaxNegativeLength : possibleMaxLength;
if (length > maxLength)
{
return false;
}
char nextChar;
while (currentIndex < length)
{
nextChar = input[currentIndex++];
if (nextChar < '0' || nextChar > '9')
{
result = 0;
return false;
}
result = result * 10 + (nextChar - '0');
if (result < 0)
{
result = 0;
return false;
}
}
if (isNegative) { result = -result; }
return true;
}
If int result is overflowing it becomes negative so we just check if result < 0 to return false.
This runs in 2065 ms vs int.TryParse in 11220 ms.
Btw. you only need the unchecked keyword if you have checked "Check for arithmetic overflow/underflow" in the advanced build settings.