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

C# 陣列清零效能大比拚:五種方法實測與最佳實踐

     編輯:關於C#

測試情境

陣列大小:byte[65536] (64KB)
迴圈:50,000 次清零
環境:P4 3.0E / DDR400 512MB / .NET Framework 1.1 (VS2003)
*現代 .NET Core/5+ 結果比例相似,絕對數值大幅下降*

五種清零方法


// 1. 重新建立陣列
test = new byte[65536];

// 2. 自訂 memset (逐元素指派)
public static void Memset(byte[] buf, byte val, int size)
{
    for (int i = 0; i < size; i++) buf[i] = val;
}
Memset(test, 0, 65536);

// 3. 內聯 for 迴圈
for (int k = 0; k < 65536; test[k++] = 0) ;

// 4. Array.Clear (BCL 內建)
Array.Clear(test, 0, 65536);

// 5. 空陣列 CopyTo
test2.CopyTo(test, 0); // test2 為預先建立的同大小零陣列

實測結果 (毫秒,10 次平均)

方法最長最短平均相對效能
1. new 陣列1937.51812.51842.23.17x
2. 自訂 Memset4593.84625.04584.47.89x
3. 內聯 for6046.95984.46001.610.32x
4. Array.Clear562.5640.5581.31.00x (基準)
5. CopyTo812.5750.0770.31.33x

深度分析

  1. Array.Clear 勝出關鍵:內部呼叫高度優化的 native 記憶體清零指令 (memset/rep stosb),並處理陣列邊界檢查、GC 卡片標記等細節。
  2. new 陣列次之:雖需重新配置記憶體,但配置器極快 (Gen0 指標遞增),且零初始化由 OS 記憶體管理單元批次完成。
  3. CopyTo 尚可:利用 `Buffer.BlockCopy` 底層複製,但需額外維護一個零陣列佔用記憶體。
  4. 手寫迴圈最慢:C# 迴圈邊界檢查、索引運算、JIT 難以向量化,效能遠輸 native 實作。內聯反而更慢 可能因指令快取壓力、缺乏方法內聯優化。

現代 .NET (Core 3.1 / 5 / 6 / 7 / 8) 補充

  • Array.Clear 依然最快,且新增 Array.Clear(Array) 多載 (清除整個陣列)。
  • RuntimeHelpers.InitBlock / Unsafe.InitBlock 可對 `stackalloc` / `Span` 做極致清零。
  • MemoryExtensions.Fill (`.NET 6+`):`span.Fill(0)` 語意清晰、效能等同 `Array.Clear`。

最佳實踐建議

場景建議做法
清零現有陣列Array.Clear(arr) 或 span.Fill(0)
重新配置同大小陣列arr = new T[size] (若不介意 GC 壓力)
需特定非零值填充span.Fill(value) 或預先備妥樣板陣列 template.CopyTo(arr)
高效能熱路徑 (Span/stackalloc)Unsafe.InitBlock(ref MemoryMarshal.GetReference(span), 0, (uint)span.Length)

總結

永遠優先使用 `Array.Clear` / `Span.Fill`** 由 BCL 提供的經過極致優化、處理邊界與 GC 協議的原生實作。手寫迴圈不僅效能差,還易出現 Off-by-one 錯誤。記住:「不要重造輪子,除非你在造更好的輪子。」

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