使用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;
}
}
根据上图看出,先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;
}
根据基准测试结果: 在.Net 9上使用Linq扩展方法和Count性能相差2%, 在.Net10上这个性能差距在5%,如何List长度较大时,这个结果可能更高,在.Net10对Linq是有性能优化,不过在本次性能基准测试中,并没有看到.
虽说.Net每年都有很多性能优化,编写代码时,还是要注意使用的方式,虽然大多数时候,对性能要求不高.但可能随着时间和数据变多时,就有可能成为性能瓶颈.比如之前我遇到 记一次事务超时
如果还在使用.NetFramework 或者 早期.Net Core版本(.Net 10之前),使用Linq较多,有需要性能的话,可以使用开源项目: ZLinq
秋风
2026-03-08