How do you optimize LINQ queries?
4 minintermediate.NETLINQperformanceoptimization
Quick Answer
Optimize LINQ by filtering early (`Where` before `Select`/ordering) to shrink the working set, avoiding multiple enumeration of the same deferred query (materialize once with `ToList`), and choosing the right operators (`Any()` instead of `Count() > 0`, `FirstOrDefault` instead of `Where(...).FirstOrDefault()`). For LINQ-to-Entities, keep queries server-side (avoid client evaluation) and project only needed columns. Avoid heavy LINQ in tight CPU loops where a plain loop is cheaper.
Detailed Answer
Optimization Techniques:
1. Use Appropriate Methods
// Bad: Materializing entire collection
if (list.Where(x => x > 5).Count() > 0)
// Good: Short-circuit evaluation
if (list.Any(x => x > 5))
2. Avoid Multiple Enumeration
// Bad: Query executed twice
var query = list.Where(x => x > 5);
var count = query.Count();
var sum = query.Sum();
// Good: Materialize once
var results = list.Where(x => x > 5).ToList();
var count = results.Count;
var sum = results.Sum();
3. Filter Early
// Bad: Select then filter
var result = list.Select(x => new { x.Id, x.Name })
.Where(x => x.Id > 100);
// Good: Filter then select
var result = list.Where(x => x.Id > 100)
.Select(x => new { x.Id, x.Name });
4. Use Proper Collection Types
// For lookups, use HashSet or Dictionary
var hashSet = new HashSet(largeList);
if (hashSet.Contains(value)) // O(1) instead of O(n)
// For indexed access, use arrays or lists
int[] array = list.ToArray(); // Better than IEnumerable for iteration
5. Avoid Unnecessary Sorting
// Bad: Sort entire collection to get top 10
var top10 = list.OrderBy(x => x.Score).Take(10);
// Good: Use efficient algorithm for top N
var top10 = list.OrderByDescending(x => x.Score).Take(10);
// Or use a priority queue for large datasets
6. Use AsParallel() for Large Datasets
// Sequential
var result = hugeList.Where(x => ExpensiveOperation(x));
// Parallel (for CPU-bound operations)
var result = hugeList.AsParallel()
.Where(x => ExpensiveOperation(x));
7. Avoid Closures in Loops
// Bad: Captured variable
for (int i = 0; i < items.Count; i++)
{
var query = list.Where(x => x.Id == i); // Captures 'i'
}
// Good: Local copy
for (int i = 0; i < items.Count; i++)
{
var index = i;
var query = list.Where(x => x.Id == index);
}
8. Use Compiled Queries for Repeated Execution
// Entity Framework example
var compiledQuery = EF.CompileQuery(
(MyContext ctx, int id) => ctx.Users.Where(u => u.Id == id)
);