Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Created February 22, 2017 17:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ufcpp/15af6d3d7606fb3771a91c81898dcfa3 to your computer and use it in GitHub Desktop.
Save ufcpp/15af6d3d7606fb3771a91c81898dcfa3 to your computer and use it in GitHub Desktop.
A benchmark code for struct generics
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Jobs;
using BenchmarkDotNet.Engines;
using System;
public interface IBinaryOperator
{
int Operate(int x, int y);
}
public struct Add : IBinaryOperator
{
public int Operate(int x, int y) => x + y;
}
public struct Mul : IBinaryOperator
{
public int Operate(int x, int y) => x * y;
}
public static class Op
{
public static int Add(int x, int y) => x + y;
public static int Mul(int x, int y) => x * y;
}
class Program
{
static void Main()
{
BenchmarkDotNet.Running.BenchmarkRunner.Run<TestBenchmark>();
}
}
[SimpleJob(RunStrategy.Throughput)]
public class TestBenchmark
{
static (int x, int y)[] _data;
static TestBenchmark()
{
var r = new Random();
_data = new(int x, int y)[10];
for (int i = 0; i < _data.Length; i++)
{
_data[i] = (r.Next(), r.Next());
}
}
[Benchmark] public static void EmbeddedAdd() { foreach (var (x, y) in _data) Embedded.Add(x, y); }
[Benchmark] public static void StaticAdd() { foreach (var (x, y) in _data) StaticMethod.Add(x, y); }
[Benchmark] public static void DefaultAdd() { foreach (var (x, y) in _data) DefaultValue.Add(x, y); }
[Benchmark] public static void TypeClassAdd() { foreach (var (x, y) in _data) TypeClass.Op<Add>(x, y); }
[Benchmark] public static void DelegateAdd() { foreach (var (x, y) in _data) DelegateParameter.Op(x, y, Op.Add); }
[Benchmark] public static void CachedDelegateAdd() { Func<int, int, int> f = Op.Add; foreach (var (x, y) in _data) DelegateParameter.Op(x, y, f); }
[Benchmark] public static void InterfaceAdd() { foreach (var (x, y) in _data) InterfaceParameter.Op(x, y, new Add()); }
[Benchmark] public static void CachedInterfaceAdd() { IBinaryOperator op = new Add(); foreach (var (x, y) in _data) InterfaceParameter.Op(x, y, op); }
[Benchmark] public static void EmbeddedMul() { foreach (var (x, y) in _data) Embedded.Mul(x, y); }
[Benchmark] public static void StaticMul() { foreach (var (x, y) in _data) StaticMethod.Mul(x, y); }
[Benchmark] public static void DefaultMul() { foreach (var (x, y) in _data) DefaultValue.Mul(x, y); }
[Benchmark] public static void TypeClassMul() { foreach (var (x, y) in _data) TypeClass.Op<Mul>(x, y); }
[Benchmark] public static void DelegateMul() { foreach (var (x, y) in _data) DelegateParameter.Op(x, y, Op.Mul); }
[Benchmark] public static void CachedDelegateMul() { Func<int, int, int> f = Op.Mul; foreach (var (x, y) in _data) DelegateParameter.Op(x, y, f); }
[Benchmark] public static void InterfaceMul() { foreach (var (x, y) in _data) InterfaceParameter.Op(x, y, new Mul()); }
[Benchmark] public static void CachedInterfaceMul() { IBinaryOperator op = new Mul(); foreach (var (x, y) in _data) InterfaceParameter.Op(x, y, op); }
}
public class Embedded
{
public static int Add(int x, int y)
{
return x + y;
}
public static int Mul(int x, int y)
{
return x * y;
}
}
public class StaticMethod
{
public static int Add(int x, int y)
{
return Op.Add(x, y);
}
public static int Mul(int x, int y)
{
return Op.Mul(x, y);
}
}
public class DefaultValue
{
public static int Add(int x, int y)
{
return default(Add).Operate(x, y);
}
public static int Mul(int x, int y)
{
return default(Mul).Operate(x, y);
}
}
public class TypeClass
{
public static int Op<T>(int x, int y)
where T : struct, IBinaryOperator
{
return default(T).Operate(x, y);
}
}
public class DelegateParameter
{
public static int Op(int x, int y, Func<int, int, int> f)
{
return f(x, y);
}
}
public class InterfaceParameter
{
public static int Op(int x, int y, IBinaryOperator op)
{
return op.Operate(x, y);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment