首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

淺談分組統計:Foreach、Iterator、LINQ 三種實作效能比較

     編輯:關於C#

分組統計是常見需求 (如反洗錢大額交易統計)。本文以「已排序資料按 Key 分組,計算各組筆數與平均值」為例,比較三種寫法的程式碼結構與效能。

測試資料生成

IEnumerable<Tuple<int, double>> GetTuples(int n)
{
    var tuples = new Tuple<int, double>[n];
    var rand = new Random();
    for (int k = 1, i = 0; i < n; i++)
    {
        var r = rand.Next(n);
        k += (r >= n - 3) ? 2 : ((r >= n - 9) ? 1 : 0);
        tuples[i] = new Tuple<int, double>(k, rand.NextDouble());
    }
    return tuples;
}

產生 n 筆已依 Key 排序的資料。

三種實作

  1. Foreach 迴圈:直觀但迴圈結束後需額外處理最後一組,「壞味道」明顯。
  2. Iterator (GetEnumerator):手動控制 MoveNext,將「組別變更」與「結束」邏輯合併,消除重複代碼。
  3. LINQ GroupBy:語法最簡潔 from k in tuples group k by k.Item1,但執行階段與記憶體開銷最大。

程式碼片段

// Foreach
foreach (var v in tuples) { if (key != v.Item1) { if (key != null) result.Add(...); sum = count = 0; key = v.Item1; } count++; sum += v.Item2; }
if (key != null) result.Add(...);

// Iterator
for (var iter = tuples.GetEnumerator(); ; count++, sum += iter.Current.Item2)
{
    var hasValue = iter.MoveNext();
    if (!hasValue || key != iter.Current.Item1)
    {
        if (key != null) result.Add(...);
        if (!hasValue) break;
        sum = count = 0; key = iter.Current.Item1;
    }
}

// LINQ
var q = from k in tuples group k by k.Item1;
foreach (var g in q) result.Add(new Tuple<int, int, double>(g.Key, g.Count(), g.Average(v => v.Item2)));

效能測試結果 (1048 萬筆資料)

三種方法輸出結果完全一致 (12 組,總筆數 10,485,760,整體平均 0.500189)。但執行速度與記憶體佔用:

  • Foreach / Iterator:速度相近,記憶體極低 (流式處理)。
  • LINQ:顯著較慢,記憶體佔用大 (需建立分組查詢物件與中間集合)。

結論

資料已排序時,Iterator 寫法最優雅且高效;未排序需先 OrderBy。LINQ 適合快速開發、資料量不大的場合。文中附完整主程式與 Tuple 定義 (.NET 4.0 內建 Tuple 可直接使用)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved