[C#] 使用 Count()==0 前想想 Any()

2025-08-12

之前在網路上看到有人說可以用 Any() 取代 Count()==0 ,效能會比較好,畢竟 Count()==0 

平常寫得很習慣,一開始我以為這只是誤差,沒想到背後居然真有明顯的效能差異,於是我動手測一下..


1. 建立兩個 function 一個是用 Any()  判斷,一個是用 Count() 判斷,裡面比較需要注意的就是 如果沒有使用 Where 

GPT表示:

Enumerable.Range(0, 10) 會回傳一個內建的 Range 迭代器。 在 .NET 裡,Count() 會先嘗試「不枚舉就拿到總數」的捷徑(例如 ICollection<T>.Count、內建迭代器的快速路徑、或 TryGetNonEnumeratedCount)。 對 Range 這種來源,總數是已知的,所以 Count() 不需要跑 foreach 就能知道答案(10)。


public static void AnyPerformance(int i) { IEnumerable<int> src; if (i % 2 == 0) { src = Enumerable.Range(0, 10).Where(x =&gt; x &gt; -1); } else { src = Enumerable.Empty<int>(); } bool emptyByCount = src.Any(); } public static void CountPerformance(int i) { IEnumerable<int> src; if (i % 2 == 0) { src = Enumerable.Range(0, 10).Where(x=&gt;x&gt;-1); } else { src = Enumerable.Empty<int>(); } bool emptyByCount = src.Count() == 0; } </int></int></int></int>


2. 之後就是主程式分別測試 一千萬次然後計算時間

var sw = Stopwatch.StartNew(); for (var i = 1; i &lt;= 10_000_000; i++) { AnyPerformance(i); } Console.WriteLine($"!Any(): {sw.ElapsedMilliseconds} ms"); var sw1 = Stopwatch.StartNew(); for (var i = 1; i &lt;= 10_000_000; i++) { CountPerformance(i); } Console.WriteLine($"Count() == 0: {sw1.ElapsedMilliseconds} ms");

結果:

!Any(): 641 ms Count() == 0: 1185 ms !Any(): 570 ms Count() == 0: 1078 ms !Any(): 594 ms Count() == 0: 1086 ms


結論:

簡單的說,如果你只要判斷那個集合是不是沒有東西,直接用 Any() 因為他的記憶體指標只檢查一個就離開了

如果你使用 Count() 他為了給你精準的數字,但是你偏偏只是要判斷是不是 沒有東西,就有點殺雞焉用核彈

一個不被注意的小事情,因為連我也是常常因為很直覺就寫了 Count()==0 這點要改改了。



當麻許的碎念筆記 2014 | Donma Hsu Design.