Method | TargetType | Mean | Error | StdDev | Gen0 | Allocated |
---|---|---|---|---|---|---|
BaseLineBenchmark | DateTimeOffset | 1.3773 ns | 0.0099 ns | 0.0077 ns | - | - |
SwitchBenchmark | DateTimeOffset | 83.2784 ns | 2.4676 ns | 7.2370 ns | 0.1023 | 856 B |
BaseLineBenchmark | Int32 | 0.0266 ns | 0.0139 ns | 0.0130 ns | - | - |
SwitchBenchmark | Int32 | 72.3950 ns | 2.0014 ns | 5.7744 ns | 0.1023 | 856 B |
BaseLineBenchmark | TimeSpan | 2.1881 ns | 0.0305 ns | 0.0286 ns | - | - |
SwitchBenchmark | TimeSpan | 72.3910 ns | 1.7300 ns | 4.9358 ns | 0.1023 | 856 B |
Last active
May 22, 2024 18:27
-
-
Save pwelter34/f6ae744f6a913cdc52ebe186edac0f22 to your computer and use it in GitHub Desktop.
TypeSwitch - Switch on runtime type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[MemoryDiagnoser] | |
public class BenchmarkSwitch | |
{ | |
[Params(typeof(int), typeof(DateTimeOffset), typeof(TimeSpan))] | |
public Type TargetType { get; set; } = typeof(int); | |
[Benchmark(Baseline = true)] | |
public int BaseLineBenchmark() | |
{ | |
if (TargetType == typeof(string)) | |
return 1; | |
if (TargetType == typeof(int)) | |
return 2; | |
if (TargetType == typeof(long)) | |
return 3; | |
if (TargetType == typeof(short)) | |
return 4; | |
if (TargetType == typeof(float)) | |
return 5; | |
if (TargetType == typeof(double)) | |
return 6; | |
if (TargetType == typeof(decimal)) | |
return 7; | |
if (TargetType == typeof(DateTime)) | |
return 8; | |
if (TargetType == typeof(DateTimeOffset)) | |
return 9; | |
if (TargetType == typeof(DateOnly)) | |
return 10; | |
if (TargetType == typeof(TimeOnly)) | |
return 11; | |
if (TargetType == typeof(Guid)) | |
return 12; | |
return 99; | |
} | |
[Benchmark] | |
public int SwitchBenchmark() | |
{ | |
int value = 0; | |
TargetType | |
.Switch() | |
.Case<string>(() => value = 1) | |
.Case<int>(() => value = 2) | |
.Case<long>(() => value = 3) | |
.Case<short>(() => value = 4) | |
.Case<float>(() => value = 5) | |
.Case<double>(() => value = 6) | |
.Case<decimal>(() => value = 7) | |
.Case<DateTime>(() => value = 8) | |
.Case<DateTimeOffset>(() => value = 9) | |
.Case<DateOnly>(() => value = 10) | |
.Case<TimeOnly>(() => value = 11) | |
.Case<Guid>(() => value = 12) | |
.Default(() => value = 99); | |
return value; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Program | |
{ | |
static void Main(string[] args) | |
{ | |
BenchmarkRunner.Run(typeof(Program).Assembly); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class TypeSwitch | |
{ | |
// switch case that indicates there was already a match | |
private static readonly SwitchCase Matched = new(typeof(SwitchCase)); | |
public static SwitchCase Switch<T>() | |
{ | |
var type = typeof(T); | |
return new SwitchCase(type); | |
} | |
public static SwitchCase Switch(this Type type) | |
{ | |
if (type is null) | |
throw new ArgumentNullException(nameof(type)); | |
return new SwitchCase(type); | |
} | |
public static SwitchCase Case<T>(this SwitchCase switchCase, Action action) | |
{ | |
if (action is null) | |
throw new ArgumentNullException(nameof(action)); | |
// already matched, short circuit | |
if (switchCase == Matched) | |
return switchCase; | |
var type = typeof(T); | |
return Case(switchCase, type, action); | |
} | |
public static SwitchCase Case(this SwitchCase switchCase, Type type, Action action) | |
{ | |
if (type is null) | |
throw new ArgumentNullException(nameof(type)); | |
if (action is null) | |
throw new ArgumentNullException(nameof(action)); | |
// already matched, short circuit | |
if (switchCase == Matched) | |
return switchCase; | |
if (type != switchCase.Type) | |
return switchCase; | |
// invoke action and return matched | |
action(); | |
return Matched; | |
} | |
public static SwitchCase Default(this SwitchCase switchCase, Action action) | |
{ | |
if (action is null) | |
throw new ArgumentNullException(nameof(action)); | |
// already matched | |
if (switchCase == Matched) | |
return switchCase; | |
// invoke action and return matched | |
action(); | |
return Matched; | |
} | |
public readonly record struct SwitchCase(Type Type); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment