Compiled RegEx vs For-Loop vs Linq Predicate

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;

namespace Playground
{
	public static class Program
	{
		private static readonly Regex Regex = new Regex("^[a-zA-Z0-9]*$", RegexOptions.Compiled);
		private static readonly Random Random = new Random();
		private static readonly Random MultipleRangeRandom = new Random();
		private static readonly Stopwatch Stopwatch = new Stopwatch();

		//49-57 = Numbers
		//65-90 = Uppercase
		//97-122 = Uppercase
		//32 = Space if you want to include it
		private static readonly List<Tuple<int,int>> MinMax = new List<Tuple<int, int>>()
		{
			new Tuple<int, int>(49, 57),
			new Tuple<int, int>( 65, 90 ),
			new Tuple<int, int>( 97, 122 )
		};

		public static void Main(string[] args)
		{
			// Pre-compile RegEx
			 Regex.IsMatch(string.Empty);
			 const int numberOfCharacters = 1000000;
			 var alphaNum = new string(GenerateRandomAlphaNumericString(numberOfCharacters).ToArray());
			 var anyChar = new string(GenerateRandomString(numberOfCharacters).ToArray());
			
			 //Matches
			Console.WriteLine($" Using Regex: {ValidateStringRegex(alphaNum)}");
			Console.WriteLine($" Using For-Loop: {ValidateStringForLoop(alphaNum)}");
			Console.WriteLine($" Using Linq Extensions: {ValidateStringExpressions(alphaNum)}");
			
			//Non-Matches
			Console.WriteLine($" Using Regex: {ValidateStringRegex(anyChar)}");
			Console.WriteLine($" Using For-Loop: {ValidateStringForLoop(anyChar)}");
			Console.WriteLine($" Using Linq Extensions: {ValidateStringExpressions(anyChar)}");
		}

		private static IEnumerable<char> GenerateRandomString(int numberOfCharacters)
		{
			for (var i = 0; i < numberOfCharacters; i++)
			{
				yield return (char)Random.Next(0, 255);
			}
		}

		private static IEnumerable<char> GenerateRandomAlphaNumericString(int numberOfCharacters)
		{
			for (var i = 0; i < numberOfCharacters; i++)
			{
				var randomIndex = MultipleRangeRandom.Next(0, MinMax.Count);
				yield return (char)Random.Next(MinMax[randomIndex].Item1, MinMax[randomIndex].Item2);
			}
		}

		private static long ValidateStringRegex(string value)
		{
			Stopwatch.Restart();
			
			Regex.IsMatch(value);
			
			Stopwatch.Stop();
			
			return Stopwatch.ElapsedMilliseconds;
		}

		public static long ValidateStringForLoop(string value)
		{
			Stopwatch.Restart();

			if (string.IsNullOrEmpty(value))
			{
				Stopwatch.Stop();
				return Stopwatch.ElapsedMilliseconds;
			}

			for (var i = 0; i < value.Length; i++)
			{
				if (!char.IsLetter(value[i]) && !char.IsNumber(value[i]))
				{
					Stopwatch.Stop();
					return Stopwatch.ElapsedMilliseconds;
				}
			}
			
			Stopwatch.Stop();
			
			return Stopwatch.ElapsedMilliseconds;
		}

		public static long ValidateStringExpressions(IEnumerable<char> value)
		{
			Stopwatch.Restart();

			value.All(c => char.IsLetter(c) || char.IsNumber(c));

			Stopwatch.Stop();
			return Stopwatch.ElapsedMilliseconds;
		}
	}
}
;