Skip to content

Instantly share code, notes, and snippets.

@svick
Last active January 22, 2023 20:22
Show Gist options
  • Save svick/c9e5141af93dc6606081a83513e43f12 to your computer and use it in GitHub Desktop.
Save svick/c9e5141af93dc6606081a83513e43f12 to your computer and use it in GitHub Desktop.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.CsProj;
using static Modified.Extensions;
public class Program
{
static void Main(string[] args) => BenchmarkRunner.Run<Benchmark>(args: args);
}
[MemoryDiagnoser]
public partial class Benchmark
{
const int n = 100000000;
[Benchmark]
public double Original()
{
Original.IArray a = new Original.Vector(n);
Original.IArray b = new Original.Vector(n);
Original.IArray c = new Original.Vector(n);
Original.IArray x = a + b + c + c;
double sum = 0.0;
for (int i = 0; i < n; i++)
sum += x[i];
return sum;
}
[Benchmark]
public double Modified()
{
Modified.Vector a = new Modified.Vector(n);
Modified.Vector b = new Modified.Vector(n);
Modified.Vector c = new Modified.Vector(n);
return ModifiedImpl(a, b, c);
}
public double ModifiedImpl<T>(T a, T b, T c) where T : Modified.IArray<T>
{
var x = a.Plus(b).Plus(c).Plus(c);
double sum = 0.0;
for (int i = 0; i < n; i++)
sum += x[i];
return sum;
}
[Benchmark]
public double HandCoded()
{
Original.IArray a = new Original.Vector(n);
Original.IArray b = new Original.Vector(n);
Original.IArray c = new Original.Vector(n);
double[] x = new double[n];
for (int i = 0; i < n; i++)
x[i] = a[i]+b[i]+c[i]+c[i];
double sum = 0.0;
for (int i = 0; i < n; i++)
sum += x[i];
return sum;
}
}
namespace Original
{
public interface IArray
{
double this[int i] { get; }
public static IArray operator +(IArray L, IArray R) => new Plus<IArray, IArray>(L, R);
}
public struct Vector : IArray
{
double[] data;
public double this[int i] => data[i];
public Vector(int n)
{ data = new double[n]; }
}
public struct Plus<Left, Right> : IArray
where Left : IArray
where Right : IArray
{
public readonly Left L;
public readonly Right R;
public Plus(Left left, Right right)
{
L = left;
R = right;
}
public double this[int i] => L[i] + R[i];
}
}
namespace Modified
{
public interface IArray<T> where T : IArray<T>
{
double this[int i] { get; }
}
static class Extensions
{
public static Plus<TL, TR> Plus<TL, TR>(this TL left, TR right) where TL : IArray<TL> where TR : IArray<TR>
=> new Plus<TL, TR>(left, right);
}
public struct Vector : IArray<Vector>
{
double[] data;
public double this[int i] => data[i];
public Vector(int n)
{ data = new double[n]; }
}
public struct Plus<Left, Right> : IArray<Plus<Left, Right>>
where Left : IArray<Left>
where Right : IArray<Right>
{
public readonly Left L;
public readonly Right R;
public Plus(Left left, Right right)
{
L = left;
R = right;
}
public double this[int i] => L[i] + R[i];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment