When working with LINQ in C#, it is recommended to pay attention to the order in which methods are chained, especially when using
Where and OrderBy methods. It is advised to call the Where method before OrderBy because
Where filters the elements of the sequence based on a given condition and returns a new sequence containing only the elements that
satisfy that condition. Calling OrderBy before Where, may end up sorting elements that will be later discarded, which can
lead to inefficiency. Conversely, calling Where before OrderBy, will first filter the sequence to include only the elements
of interest, and then sort them based on the specified order.
We measured at least 2x improvement in execution time. For more details see the Benchmarks section from the More info
tab.
The issue can be fixed by calling Where before OrderBy.
public IEnumerable<int> GetSortedFilteredList(IEnumerable<int> data) =>
data.OrderBy(x => x).Where(x => x % 2 == 0);
public IEnumerable<int> GetSortedFilteredList(IEnumerable<int> data) =>
data.Where(x => x % 2 == 0).OrderBy(x => x);
| Method | Runtime | Mean | StdDev | Ratio |
|---|---|---|---|---|
OrderByThenWhere |
.NET 7.0 |
175.36 ms |
5.101 ms |
1.00 |
WhereThenOrderBy |
.NET 7.0 |
85.58 ms |
1.697 ms |
0.48 |
The results were generated by running the following snippet with BenchmarkDotNet:
private IList<int> data;
private static readonly Random Random = new Random();
[Params(1_000_000)]
public int NumberOfEntries;
[GlobalSetup]
public void Setup() =>
data = Enumerable.Range(0, NumberOfEntries).Select(x => Random.Next(0, NumberOfEntries)).ToList();
[Benchmark(Baseline = true)]
public void OrderByThenWhere() =>
_ = data.OrderBy(x => x).Where(x => x % 2 == 0 ).ToList(); // OrderBy followed by Where
[Benchmark]
public void WhereThenOrderBy() =>
_ = data.Where(x => x % 2 == 0 ).OrderBy(x => x).ToList(); // Where followed by OrderBy
Hardware configuration:
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update) 12th Gen Intel Core i7-12800H, 1 CPU, 20 logical and 14 physical cores .NET SDK=7.0.203 [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 .NET 7.0 : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2