陣列大小: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 為預先建立的同大小零陣列
| 方法 | 最長 | 最短 | 平均 | 相對效能 |
|---|---|---|---|---|
| 1. new 陣列 | 1937.5 | 1812.5 | 1842.2 | 3.17x |
| 2. 自訂 Memset | 4593.8 | 4625.0 | 4584.4 | 7.89x |
| 3. 內聯 for | 6046.9 | 5984.4 | 6001.6 | 10.32x |
| 4. Array.Clear | 562.5 | 640.5 | 581.3 | 1.00x (基準) |
| 5. CopyTo | 812.5 | 750.0 | 770.3 | 1.33x |
Array.Clear 依然最快,且新增 Array.Clear(Array) 多載 (清除整個陣列)。RuntimeHelpers.InitBlock / Unsafe.InitBlock 可對 `stackalloc` / `SpanMemoryExtensions.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 錯誤。記住:「不要重造輪子,除非你在造更好的輪子。」