230 lines
7.0 KiB
C#
230 lines
7.0 KiB
C#
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);
|
|
|
|
[Benchmark]
|
|
public int CompareFast() => m_Original.CompareFastTo(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<RefSpanScore>
|
|
{
|
|
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<RefSpanScore> 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 int CompareFastTo(object? obj)
|
|
{
|
|
if (!(obj is Score other))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return ScoreFlag.CompareTo(other.ScoreFlag);
|
|
}
|
|
|
|
public bool Equals(RefSpanScore? other)
|
|
{
|
|
return ReferenceEquals(this, other);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public class Program
|
|
{
|
|
public static void Main(string[] args)
|
|
{
|
|
var summary = BenchmarkRunner.Run<ScoreComparer>();
|
|
}
|
|
}
|
|
} |