using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
public class ColumnComparer : IComparer<Row>
public ColumnComparer(int column)
public int Column { get; }
public int Compare(Row x, Row y) => x.Values[Column].CompareTo(y.Values[Column]);
public class DummyComparer<T> : IComparer<T>
public int Compare(T x, T y) => throw new ApplicationException($"Here is the traceback at which IComparer<{typeof(T).Name}>.CompareTo(x, y) is called");
public int Index { get; }
public List<double> Values { get; } = new();
private readonly List<Row> _rows;
for (int i = 0; i < 45000; ++i)
for (int j = 0; j < 32; ++j)
row.Values.Add(r.Next(0, 1000));
var sort2 = _rows.OrderBy(x => x.Values[8]).ToArray();
var comparer = new ColumnComparer(8);
var sort2 = _rows.OrderBy(e => e, comparer).ToArray();
.Select(row => (row, value : row.Values[8]))
.Select(p => p.row).ToArray();
var sort2 = _rows.OrderBy(x => x.Values[8], new DummyComparer<double>() ).ToArray();
var sort2 = _rows.OrderBy(r => r, new DummyComparer<Row>() ).ToArray();
static TimeSpan Time(Action action, int count)
var stopwatch = new System.Diagnostics.Stopwatch();
for (int i = 0; i < count; i++)
return stopwatch.Elapsed;
static void Main(string[] args)
var elapsed1 = Time(() => sort.Sort1(), count);
var elapsed2 = Time(() => sort.Sort2(), count);
var elapsed3 = Time(() => sort.Sort3(), count);
Console.WriteLine("Average time per repetition for {0} reps of Sort1: {1:0.0000} ms.", count, elapsed1.TotalMilliseconds/((double)count));
Console.WriteLine("Average time per repetition for {0} reps of Sort2: {1:0.0000} ms ({2:0.00}% slower).", count, elapsed2.TotalMilliseconds/((double)count), -100.0*(elapsed1 - elapsed2)/elapsed1);
Console.WriteLine("Average time per repetition for {0} reps of Sort3: {1:0.0000} ms ({2:0.00}% slower).", count, elapsed3.TotalMilliseconds/((double)count), -100.0*(elapsed1 - elapsed3)/elapsed1);
Console.WriteLine("\nTraceback for _rows.OrderBy(x => x.Values[8]).ToArray():");
Console.WriteLine("\n_rows.OrderBy(e => e, comparer).ToArray():");
Console.WriteLine(Comparer<double>.Default);