C#中Any与Exists方法选择困惑:VS推荐Exists为何Any更快?
列表包含检查:Exists与Any方法的性能差异疑问
需求
检查一个列表中的元素是否存在于另一个列表的元素中(即判断words里的任意单词是否被txtList中的某个字符串包含)
测试代码
List<string> words = new(){"the","play","in","on"}; string txt="Barcelona is playing against Manchester tonight."; List<string> txtList=txt.Split(' ', StringSplitOptions.RemoveEmptyEntries).ToList(); bool exist = false; Stopwatch sw; Stopwatch sw2; sw = Stopwatch.StartNew(); for (int i=0; i<1000 ;i++) { exist = words.Exists(w => txtList.Exists(t => t.Contains(w))); } sw.Stop(); Console.WriteLine("ExistResult: "+ exist + Environment.NewLine + "ExistTime: " + sw.ElapsedTicks); sw2 = Stopwatch.StartNew(); for (int i=0; i<1000 ;i++) { exist = words.Any(w => txtList.Any(t => t.Contains(w))); } sw2.Stop(); Console.WriteLine("AnyResult: "+ exist + Environment.NewLine + "AnyTime: " + sw2.ElapsedTicks);
测试结果
ExistResult: True
ExistTime: 2574053
AnyResult: True
AnyTime: 1265826
疑问
测试发现Any方法的速度几乎是Exists的两倍,但Visual Studio却推荐使用Exists方法,这是为什么?
解答
首先得明确Exists和Any的本质区别:
Exists是**List<T>专属的实例方法**,属于.NET早期原生API,设计初衷就是针对List类型做适配;而Any是LINQ扩展方法,属于System.Linq.Enumerable类,能适配所有IEnumerable<T>类型,包括数组、自定义集合等。
Visual Studio的推荐逻辑主要基于这几点:
- 语义精准性:
Exists的命名完全贴合“检查列表内是否存在符合条件元素”的场景,操作List<T>时用专属方法,代码意图比通用LINQ方法更明确。 - 历史设计定位:在LINQ出现(.NET 3.5)之前,
List<T>.Exists就是检查元素存在的标准方式,VS的代码分析规则会倾向于推荐类型专属的原生API,而非跨类型的通用扩展方法。 - 测试场景的局限性:你这次的性能差异是大量循环(1000次)放大后的结果,实际业务中单次调用的差异几乎感知不到。而且
Exists在小集合、简单判断逻辑下的性能和Any差距极小,甚至可能持平。 - 代码分析规则导向:VS的代码分析规则(比如CA1822)会优先推荐用类型专属方法替代LINQ扩展方法,目的是减少不必要的抽象层开销,让代码更贴近类型原生能力。
另外要注意,Exists和Any底层都是短路求值——遍历到符合条件的元素就立即返回,逻辑本质高度相似。你测试中的性能差,更多是LINQ扩展方法的委托包装、接口调用带来的微小额外开销,在大量循环下被放大了而已。
内容的提问来源于stack exchange,提问作者ioxoi
相关产品推荐
相关产品推荐

