-
Notifications
You must be signed in to change notification settings - Fork 11
Open
Description
When performing different actions based on the value of an enumeration tipe (like the ZipEntrySource enumeration), I think it is worth considering switch statements or switch expression statements instead of repeated if else statements.
A test using BenchmarkDotNet gave these results:
// * Summary *
BenchmarkDotNet v0.15.0, Linux Linux Mint 22.1 (Xia)
Intel Core i7-4800MQ CPU 2.70GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
.NET SDK 9.0.300
[Host] : .NET 9.0.5 (9.0.525.21509), X64 RyuJIT AVX2
DefaultJob : .NET 9.0.5 (9.0.525.21509), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev |
|----------------- |-----------:|--------:|--------:|
| IfElse | 1,040.0 ns | 9.28 ns | 8.23 ns |
| Switch | 326.4 ns | 6.23 ns | 6.12 ns |
| SwitchExpression | 291.7 ns | 5.76 ns | 7.08 ns |
The Benchmark class used was this:
public abstract class BenchmarkTestsBase<T>
{
protected readonly int _iterations;
protected readonly T[] _inputData;
protected BenchmarkTestsBase(int iterations, Func<int, T> getInputItem)
{
_iterations = iterations;
_inputData = new T[_iterations];
for (int i = 0; i < _iterations; i++)
{
_inputData[i] = getInputItem(i);
}
}
}
public class SwitchVsIfElseOnEnumerationBenchmarkTests : BenchmarkTestsBase<ZipEntrySource>
{
public SwitchVsIfElseOnEnumerationBenchmarkTests() :
base(1000, idx => (ZipEntrySource)(idx % 6))
{ }
[Benchmark]
public void IfElse()
{
ZipEntrySource result;
for (int i = 0; i < _iterations; i++)
{
if (_inputData[i] == ZipEntrySource.FileSystem)
{
result = ZipEntrySource.FileSystem;
}
else if (_inputData[i] == ZipEntrySource.Stream)
{
result = ZipEntrySource.Stream;
}
else if (_inputData[i] == ZipEntrySource.ZipFile)
{
result = ZipEntrySource.ZipFile;
}
else if (_inputData[i] == ZipEntrySource.WriteDelegate)
{
result = ZipEntrySource.WriteDelegate;
}
else if (_inputData[i] == ZipEntrySource.JitStream)
{
result = ZipEntrySource.JitStream;
}
else
{
result = ZipEntrySource.None;
}
}
}
[Benchmark]
public void Switch()
{
ZipEntrySource result;
for (int i = 0; i < _iterations; i++)
{
switch (_inputData[i])
{
case ZipEntrySource.FileSystem:
result = ZipEntrySource.FileSystem;
break;
case ZipEntrySource.Stream:
result = ZipEntrySource.Stream;
break;
case ZipEntrySource.ZipFile:
result = ZipEntrySource.ZipFile;
break;
case ZipEntrySource.WriteDelegate:
result = ZipEntrySource.WriteDelegate;
break;
case ZipEntrySource.JitStream:
result = ZipEntrySource.JitStream;
break;
default:
result = ZipEntrySource.None;
break;
}
}
}
[Benchmark]
public void SwitchExpression()
{
ZipEntrySource result;
for (int i = 0; i < _iterations; i++)
{
result = _inputData[i] switch
{
ZipEntrySource.FileSystem => ZipEntrySource.FileSystem,
ZipEntrySource.Stream => ZipEntrySource.Stream,
ZipEntrySource.ZipFile => ZipEntrySource.ZipFile,
ZipEntrySource.WriteDelegate => ZipEntrySource.WriteDelegate,
ZipEntrySource.JitStream => ZipEntrySource.JitStream,
_ => ZipEntrySource.None
};
}
}
}
using a copy of the ZipEntrySource enumeration in the test.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels