using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; namespace MyBenchmarks { public class ScoreComparer { [Params(0, 1, 2, 3, 4)] public int OriginalIndex; [Params(0, 1, 2, 3, 4)] public int AlternateIndex; [GlobalSetup] public void GlobalSetup() { m_OriginalArray = RefArrayScore.AscendingScores[OriginalIndex]; m_AlternateArray = RefArrayScore.AscendingScores[AlternateIndex]; m_OriginalSpan = RefSpanScore.AscendingScores.Span[OriginalIndex]; m_AlternateSpan = RefSpanScore.AscendingScores.Span[AlternateIndex]; m_Original = new Score { ScoreFlag = OriginalIndex }; m_Alternate = new Score { ScoreFlag = AlternateIndex }; } private RefArrayScore m_OriginalArray = RefArrayScore.MissMatch; private RefArrayScore m_AlternateArray = RefArrayScore.MissMatch; private RefSpanScore m_OriginalSpan = RefSpanScore.MissMatch; private RefSpanScore m_AlternateSpan = RefSpanScore.MissMatch; private Score m_Original = new Score { ScoreFlag = Score.MissMatch }; private Score m_Alternate = new Score { ScoreFlag = Score.MissMatch }; [Benchmark] public int CompareArray() => m_OriginalArray.CompareTo(m_AlternateArray); [Benchmark] public int CompareSpan() => m_OriginalSpan.CompareTo(m_AlternateSpan); [Benchmark] public int Compare() => m_Original.CompareTo(m_Original); public sealed class RefArrayScore : IComparable { public static RefArrayScore MissMatch { get; } = new RefArrayScore(); public static RefArrayScore NameAndTypeMatch { get; } = new RefArrayScore(); public static RefArrayScore NameMatch { get; } = new RefArrayScore(); public static RefArrayScore TypeMatch { get; } = new RefArrayScore(); public static RefArrayScore PerfectMach { get; } = new RefArrayScore(); public static RefArrayScore[] AscendingScores { get; } = new[] { MissMatch, TypeMatch, NameMatch, NameAndTypeMatch, PerfectMach }; public int CompareTo(object? obj) { if (!(obj is RefArrayScore other)) { return -1; } var myIndex = Array.IndexOf(AscendingScores, this); var otherIndex = Array.IndexOf(AscendingScores, other); return myIndex.CompareTo(otherIndex); } } public sealed class RefSpanScore : IComparable, IEquatable { public static RefSpanScore MissMatch { get; } = new RefSpanScore(); public static RefSpanScore NameAndTypeMatch { get; } = new RefSpanScore(); public static RefSpanScore NameMatch { get; } = new RefSpanScore(); public static RefSpanScore TypeMatch { get; } = new RefSpanScore(); public static RefSpanScore PerfectMach { get; } = new RefSpanScore(); public static ReadOnlyMemory AscendingScores { get; } = new[] { MissMatch, TypeMatch, NameMatch, NameAndTypeMatch, PerfectMach }; public int CompareTo(object? obj) { if (!(obj is RefSpanScore other)) { return -1; } var myIndex = AscendingScores.Span.IndexOf(this); var otherIndex = AscendingScores.Span.IndexOf(other); return myIndex.CompareTo(otherIndex); } public bool Equals(RefSpanScore? other) { return ReferenceEquals(this, other); } } public sealed class Score : IComparable { public const int MissMatch = 0; public const int NameAndTypeMatch = 3; public const int NameMatch = 2; public const int TypeMatch = 1; public const int PerfectMach = 4; public int ScoreFlag { get; init; } public int CompareTo(object? obj) { if (!(obj is Score other)) { return -1; } if (ScoreFlag == PerfectMach && other.ScoreFlag == PerfectMach) { return 0; } if (ScoreFlag == PerfectMach && other.ScoreFlag != PerfectMach) { return 1; } if (ScoreFlag != PerfectMach && other.ScoreFlag == PerfectMach) { return -1; } if (ScoreFlag == NameAndTypeMatch && other.ScoreFlag == NameAndTypeMatch) { return 0; } if (ScoreFlag == NameAndTypeMatch && other.ScoreFlag != NameAndTypeMatch) { return 1; } if (ScoreFlag != NameAndTypeMatch && other.ScoreFlag == NameAndTypeMatch) { return -1; } if (ScoreFlag == NameMatch && other.ScoreFlag == NameMatch) { return 0; } if (ScoreFlag == NameMatch && other.ScoreFlag != NameMatch) { return 1; } if (ScoreFlag != NameMatch && other.ScoreFlag == NameMatch) { return -1; } if (ScoreFlag == TypeMatch && other.ScoreFlag == TypeMatch) { return 0; } if (ScoreFlag == TypeMatch && other.ScoreFlag != TypeMatch) { return 1; } if (ScoreFlag != TypeMatch && other.ScoreFlag == TypeMatch) { return -1; } return 0; } public bool Equals(RefSpanScore? other) { return ReferenceEquals(this, other); } } } public class Program { public static void Main(string[] args) { var summary = BenchmarkRunner.Run(); } } }