using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
VeryLongEnumNameForTesting = 999
private static readonly Dictionary<(Type, string), object> enumCache = new Dictionary<(Type, string), object>();
private static readonly string[] testInputs = new string[] {
"Value1", "Value2", "Value3", "Value10", "Value100", "VeryLongEnumNameForTesting",
"1", "2", "3", "10", "100", "999",
"", null, "InvalidValue", "999999"
public static void Main()
const int iterations = 10000;
const int warmupIterations = 500;
ValidateImplementations();
Console.WriteLine("Warming up...");
for (int i = 0; i < warmupIterations; i++)
foreach (var input in testInputs)
Original_StringToEnum<TestEnum>(input);
Optimized1_StringToEnum<TestEnum>(input);
Optimized2_StringToEnum<TestEnum>(input);
Optimized3_StringToEnum<TestEnum>(input);
var methods = new List<(string name, Func<TestEnum[]> method)>
var results = new TestEnum[testInputs.Length];
for (int i = 0; i < testInputs.Length; i++)
results[i] = Original_StringToEnum<TestEnum>(testInputs[i]);
var results = new TestEnum[testInputs.Length];
for (int i = 0; i < testInputs.Length; i++)
results[i] = Optimized1_StringToEnum<TestEnum>(testInputs[i]);
var results = new TestEnum[testInputs.Length];
for (int i = 0; i < testInputs.Length; i++)
results[i] = Optimized2_StringToEnum<TestEnum>(testInputs[i]);
var results = new TestEnum[testInputs.Length];
for (int i = 0; i < testInputs.Length; i++)
results[i] = Optimized3_StringToEnum<TestEnum>(testInputs[i]);
var benchmarkResults = new List<BenchmarkResult>();
foreach (var (name, method) in methods)
Console.WriteLine($"\nBenchmarking {name}");
var result = BenchmarkMethod(name, iterations, method);
benchmarkResults.Add(new BenchmarkResult {
AverageTime = result.Average,
MemoryUsage = result.MemoryUsage
Console.WriteLine("\n===== BENCHMARK SUMMARY =====");
foreach (var result in benchmarkResults)
Console.WriteLine($"{result.Name,-10} - Avg: {result.AverageTime,8:F3}ms, Min: {result.MinTime,8:F3}ms, Max: {result.MaxTime,8:F3}ms, Memory: {result.MemoryUsage,8:N0} bytes");
var fastestMethod = benchmarkResults.OrderBy(r => r.AverageTime).First();
var lowestMemoryMethod = benchmarkResults.OrderBy(r => r.MemoryUsage).First();
Console.WriteLine("\n===== RESULTS =====");
Console.WriteLine($"FASTEST: {fastestMethod.Name} ({fastestMethod.AverageTime:F3}ms)");
Console.WriteLine($"LOWEST MEMORY: {lowestMemoryMethod.Name} ({lowestMemoryMethod.MemoryUsage:N0} bytes)");
var originalResult = benchmarkResults.First(r => r.Name == "Original");
Console.WriteLine("\n===== PERFORMANCE COMPARISON =====");
foreach (var result in benchmarkResults.Where(r => r.Name != "Original"))
double timeImprovement = (originalResult.AverageTime - result.AverageTime) / originalResult.AverageTime * 100;
double memoryImprovement = (originalResult.MemoryUsage - result.MemoryUsage) / (double)originalResult.MemoryUsage * 100;
Console.WriteLine($"{result.Name} vs Original: " +
$"Time: {(timeImprovement >= 0 ? "faster by" : "slower by")} {Math.Abs(timeImprovement):F2}%, " +
$"Memory: {(memoryImprovement >= 0 ? "reduced by" : "increased by")} {Math.Abs(memoryImprovement):F2}%");
private static void ValidateImplementations()
Console.WriteLine("Validating implementation correctness...");
foreach (var input in testInputs)
var original = Original_StringToEnum<TestEnum>(input);
var opt1 = Optimized1_StringToEnum<TestEnum>(input);
var opt2 = Optimized2_StringToEnum<TestEnum>(input);
var opt3 = Optimized3_StringToEnum<TestEnum>(input);
if (!EqualityComparer<TestEnum>.Default.Equals(original, opt1) ||
!EqualityComparer<TestEnum>.Default.Equals(original, opt2) ||
!EqualityComparer<TestEnum>.Default.Equals(original, opt3))
Console.WriteLine($"Inconsistent results for input '{input ?? "null"}': " +
$"Original={original}, Opt1={opt1}, Opt2={opt2}, Opt3={opt3}");
Console.WriteLine($"Error validating input '{input ?? "null"}': {ex.Message}");
Console.WriteLine("All implementations return consistent results.");
Console.WriteLine("WARNING: Implementations return different results!");
private static (double Average, double Min, double Max, long MemoryUsage) BenchmarkMethod(
var times = new double[trials];
for (int trial = 0; trial < trials; trial++)
GC.WaitForPendingFinalizers();
long memoryBefore = trial == 0 ? GC.GetTotalMemory(true) : 0;
var sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
long memoryAfter = trial == 0 ? GC.GetTotalMemory(false) : 0;
memoryUsage = memoryAfter - memoryBefore;
times[trial] = sw.ElapsedMilliseconds;
Console.WriteLine($"{name} Trial {trial + 1}: {times[trial]:F3}ms");
Average: times.Average(),
public class BenchmarkResult
public string Name { get; set; }
public double AverageTime { get; set; }
public double MinTime { get; set; }
public double MaxTime { get; set; }
public long MemoryUsage { get; set; }
public static T Original_StringToEnum<T>(string Value)
if (string.IsNullOrEmpty(Value))
else if (IsInteger(Value))
var result = (T)Enum.ToObject(typeof(T), BC_Fmt.CInt(Value));
if (!Enum.IsDefined(typeof(T), result))
T res = (T)Enum.Parse(typeof(T), Value);
if (!Enum.IsDefined(typeof(T), res))
public static T Optimized1_StringToEnum<T>(string Value) where T : struct
if (string.IsNullOrEmpty(Value))
if (int.TryParse(Value, out int intValue))
T result = (T)Enum.ToObject(typeof(T), intValue);
if (Enum.IsDefined(typeof(T), result))
if (Enum.TryParse<T>(Value, true, out T parsedValue) &&
Enum.IsDefined(typeof(T), parsedValue))
public static T Optimized2_StringToEnum<T>(string Value) where T : struct
if (string.IsNullOrEmpty(Value))
var key = (typeof(T), Value);
if (enumCache.TryGetValue(key, out object cachedValue))
if (int.TryParse(Value, out int intValue))
result = (T)Enum.ToObject(typeof(T), intValue);
if (!Enum.IsDefined(typeof(T), result))
else if (Enum.TryParse<T>(Value, true, out T parsedValue) &&
Enum.IsDefined(typeof(T), parsedValue))
public static T Optimized3_StringToEnum<T>(string Value)
if (string.IsNullOrEmpty(Value))
Type enumType = typeof(T);
if (Value.Length > 0 && char.IsDigit(Value[0]))
int digit = Value[0] - '0';
T result = (T)Enum.ToObject(enumType, digit);
if (Enum.IsDefined(enumType, result))
if (int.TryParse(Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int intValue))
T result = (T)Enum.ToObject(enumType, intValue);
if (Enum.IsDefined(enumType, result))
T result = (T)Enum.Parse(enumType, Value, true);
if (Enum.IsDefined(enumType, result))
public static bool IsInteger(string Value)
if (string.IsNullOrEmpty(Value))
ReadOnlySpan<char> span = Value.AsSpan().Trim();
if (span.Length > 0 && (span[0] == '-' || span[0] == '+'))
for (int i = startIndex; i < span.Length; i++)
if ((uint)(span[i] - '0') > 9)
public static class BC_Fmt
public static int CInt<T>(T Value)
throw new ArgumentNullException(nameof(Value), "BC_Fmt.CInt() failed to convert Value is null");
if (Value is string strValue)
if (int.TryParse(strValue, out int result))
if (double.TryParse(strValue, out double dblResult))
throw new FormatException($"BC_Fmt.CInt() failed to convert string '{strValue}' to int");
if (Value is IConvertible convertible)
return convertible.ToInt32(null);
throw new InvalidCastException($"BC_Fmt.CInt() failed to convert {Value.GetType()} to int");