using System; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using BenchmarkDotNet.Attributes; namespace Benchmark { [MemoryDiagnoser] public class TrailingNumberFromString { private readonly Regex _regex = new Regex(@"^\d$", RegexOptions.Compiled); [Benchmark] public int? GetTrailingNumberFromString1() { const string foo = "Test1234"; string sValue = null; for (var i = foo.Length - 1; i >= 0; i--) { var regex = new Regex(@"^\d$"); if (regex.IsMatch(foo[i].ToString())) sValue = foo[i] + sValue; else break; } if (sValue != null) return Convert.ToInt32(sValue); return null; } [Benchmark] public int? GetTrailingNumberFromString2() { const string foo = "Test1234"; string sValue = null; for (var i = foo.Length - 1; i >= 0; i--) { if (_regex.IsMatch(foo[i].ToString())) sValue = foo[i] + sValue; else break; } if (sValue != null) return Convert.ToInt32(sValue); return null; } [Benchmark] public int? GetTrailingNumberFromString3() { const string foo = "Test1234"; var result = 0; for (var i = foo.Length - 1; i >= 0; i--) { if (foo[i] >= 48 && foo[i] <= 58) { var value = foo[i] - 48; result += value * (int) Math.Pow(10, foo.Length - i - 1); continue; } break; } return result; } [Benchmark] public int? GetTrailingNumberFromString4() { const string foo = "Test1234"; var result = 0; for (var i = foo.Length - 1; i >= 0; i--) { if (foo[i] >= 48 && foo[i] <= 58) { var value = foo[i] - 48; result += value * IntegerPow(10, foo.Length - i - 1); continue; } break; } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int IntegerPow(int x, int y) { if (y == 0) return 1; var result = x; for (var i = 1; i < y; i++) { result *= x; } return result; } [Benchmark] public int? GetTrailingNumberFromString5() { const string foo = "Test1234"; var regex = new Regex(@"\d+$"); var match = regex.Match(foo); return match.Success && int.TryParse(match.Value, out var result) ? result : default(int?); } } }