使用Linq注意事项

前言

最近在项目中见到一些不太好的使用方式,虽然不影响结构,但对性能影响也不大,如果较真的说,都使用Linq了,要什么性能.不过在使用的时候,能用更好的方式,不好吗!

不好的实例

int[] arr = [1, 2, 3, 4, 5];
var firstValue = arr.Where(d => d > 0).FirstOrDefault(); //不好
var count = arr.Count();		//不好

较好的处理

var value = arr.FirstOrDefault(d => d > 0);  //减少一次Where调用,性能更好,即使在.Net10 也没有省掉Where调用开销

var lent = arr.Length;  //如果是数组调用Length属性,性能最好,因为Count是一个扩展方法,而Length是数组的内置属性,没有调用开销
			//如果是List调用Count属性,性能最好,因为Count是List的内置属性,没有调用开销

性能测试

测试代码:
[DisassemblyDiagnoser(printSource: true, maxDepth: 2)]
[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
public class WhereTest
{
	[Params(64)]
	public int Count { get; set; }

	public static List<int> Values1 => [.. Enumerable.Range(0, 16)];

	public static List<int> Values2 => [.. Enumerable.Range(0, 64)];

	[Benchmark(Baseline = true)]
	public int WhereFirstOrDefault16()
	{
		int sum = 0;
		for (int i = 0; i < Count; i++)
		{
			var val = Values1.Where(d => d > 0).FirstOrDefault();
			sum += val;
		}

		return sum;
	}

	[Benchmark]
	public int FirstOrDefault16()
	{
		int sum = 0;
		for (int i = 0; i < Count; i++)
		{
			var val = Values1.FirstOrDefault(d => d > 0);
			sum += val;
		}

		return sum;
	}

	[Benchmark]
	public int WhereFirstOrDefault32()
	{
		int sum = 0;
		for (int i = 0; i < Count; i++)
		{
			var val = Values2.Where(d => d > 0).FirstOrDefault();
			sum += val;
		}

		return sum;
	}

	[Benchmark]
	public int FirstOrDefault32()
	{
		int sum = 0;
		for (int i = 0; i < Count; i++)
		{
			var val = Values2.FirstOrDefault(d => d > 0);
			sum += val;
		}

		return sum;
	}
}


Linq中一些性能注意事项,
根据上图看出,先Where和FirstOrDefualt的性能没有直接使用FirstOrDefualt好,性能差距在25%和28%之间.这里没测试多版本. 

看看Length/Count代替Count()
[Benchmark(Baseline = true)]
public int ListCountExtension()
{
	int sum = 0;
	for (int i = 0; i < Count; i++)
	{
		var val = Values2.Count();
		sum += val;
	}

	return sum;
}


[Benchmark]
public int ListCount()
{
	int sum = 0;
	for (int i = 0; i < Count; i++)
	{
		var val = Values2.Count;
		sum += val;
	}

	return sum;
}

使用Length/Count代替Count扩展方法,提高性能

根据基准测试结果: 在.Net 9上使用Linq扩展方法和Count性能相差2%, 在.Net10上这个性能差距在5%,如何List长度较大时,这个结果可能更高,在.Net10对Linq是有性能优化,不过在本次性能基准测试中,并没有看到.

虽说.Net每年都有很多性能优化,编写代码时,还是要注意使用的方式,虽然大多数时候,对性能要求不高.但可能随着时间和数据变多时,就有可能成为性能瓶颈.比如之前我遇到 记一次事务超时


如果还在使用.NetFramework 或者 早期.Net Core版本(.Net 10之前),使用Linq较多,有需要性能的话,可以使用开源项目: ZLinq

秋风 2026-03-08