Created
February 8, 2012 12:36
-
-
Save jcdickinson/1769044 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Globalization; | |
using System.Text.RegularExpressions; | |
using System.Diagnostics; | |
namespace ConsoleApplication2 | |
{ | |
class Program | |
{ | |
const string Test = "0x109237590827192938749123478234aefeadf1029481984901824290184"; | |
const int Iterations = 1000000; | |
static void Main(string[] args) | |
{ | |
Profile(IsHexRegexSlow, "Regex with no compiled/cached Regex"); | |
Profile(IsHexRegexFast, "Regex with compiled/cached Regex"); | |
Profile(IsHexFast, "Hand-written"); | |
Console.ReadLine(); | |
} | |
static void Profile(Func<string, bool> method, string description) | |
{ | |
var sw = new Stopwatch(); | |
// Warm up | |
method(Test); | |
sw.Start(); | |
for (var i = 0; i < Iterations; i++) | |
method(Test); | |
sw.Stop(); | |
Console.WriteLine("{0} took {1}ms", description, sw.ElapsedMilliseconds); | |
} | |
static bool IsHexRegexSlow(string value) | |
{ | |
return Regex.IsMatch(value, "^0x(?:[0-9A-Fa-f]{2})+$"); | |
} | |
static readonly Regex HexRegex = new Regex("^0x(?:[0-9A-Fa-f]{2})+$", RegexOptions.Compiled | RegexOptions.CultureInvariant); | |
static bool IsHexRegexFast(string value) | |
{ | |
return HexRegex.IsMatch(value); | |
} | |
static bool IsHexFast(string value) | |
{ | |
if (string.IsNullOrEmpty(value) || value.Length < 3) | |
return false; | |
const byte State_Zero = 0; | |
const byte State_X = 1; | |
const byte State_Value = 2; | |
var state = State_Zero; | |
for (var i = 0; i < value.Length; i++) | |
{ | |
switch (value[i]) | |
{ | |
case '0': | |
{ | |
// Can be used in either Value or Zero. | |
switch (state) | |
{ | |
case State_Zero: state = State_X; break; | |
case State_X: return false; | |
case State_Value: break; | |
} | |
} | |
break; | |
case 'X': case 'x': | |
{ | |
// Only valid in X. | |
switch (state) | |
{ | |
case State_Zero: return false; | |
case State_X: state = State_Value; break; | |
case State_Value: return false; | |
} | |
} | |
break; | |
case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': | |
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': | |
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': | |
{ | |
// Only valid in Value. | |
switch (state) | |
{ | |
case State_Zero: return false; | |
case State_X: return false; | |
case State_Value: break; | |
} | |
} | |
break; | |
default: return false; | |
} | |
} | |
return state == State_Value; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment