軟體效能優化的前提是「可測量」。.NET Framework 2.0 引入的 System.Diagnostics.Stopwatch 類別,提供了比傳統 DateTime 高得多的精度(可達微秒/百萬分之一秒),是進行程式碼區塊執行時間測量的標準工具。本文詳細說明其用法、屬性選擇與常見誤區。
DateTime.Now 精度約 10-15 毫秒;Stopwatch 利用硬體高效能計時器,精度可達 0.0001 毫秒(100 奈秒)。Start()、Stop()、Reset()、Restart()。| 成員 | 類型 | 說明 |
|---|---|---|
| Start() | 方法 | 開始/繼續計時 |
| Stop() | 方法 | 暫停計時 |
| Reset() | 方法 | 歸零並停止 |
| Restart() | 方法 | 歸零並立即開始(等同 Reset+Start) |
| Elapsed | TimeSpan | 總經過時間,最高精度,適合格式化輸出 |
| ElapsedMilliseconds | long | 總毫秒數(整數),精度較低,適合較長區間 |
| ElapsedTicks | long | 原始計時器節拍數,需配合 Frequency 換算 |
| Frequency | static long | 每秒節拍數(唯讀),由硬體/OS 決定 |
| IsRunning | bool | 是否正在計時 |
| StartNew() | static 方法 | 建立實例並立即開始(工廠模式) |
using System;
using System.Diagnostics;
namespace PerfDemo
{
class Program
{
static void Main()
{
var sw = Stopwatch.StartNew(); // 建立並啟動
long total = 0;
for (int i = 1; i <= 10_000_000; i++)
total += i;
sw.Stop();
// 1 Tick = 100 奈秒 = 0.1 微秒
decimal microseconds = sw.Elapsed.Ticks / 10m;
Console.WriteLine($"執行時間: {microseconds:F1} 微秒");
Console.WriteLine($"等同: {sw.ElapsedMilliseconds} 毫秒");
Console.WriteLine($"原始 Ticks: {sw.ElapsedTicks:N0} (Frequency={Stopwatch.Frequency:N0})");
}
}
}
TotalMilliseconds、TotalMicroseconds(.NET 6+)、Ticks 等豐富屬性,格式化輸出最靈活。TimeSpan 物件分配開銷。秒數 = ElapsedTicks / (double)Frequency。Release 模式且無偵錯器附加執行。total)或標記變量 volatile。GC.Collect()、GC.WaitForPendingFinalizers()、再 GC.Collect(),減少測量中觸發 GC 的機率。public static class Benchmark
{
public static double Time(Action action, int iterations = 100)
{
// 預熱
for (int i = 0; i < 5; i++) action();
var sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++) action();
sw.Stop();
return sw.Elapsed.TotalMilliseconds / iterations; // 平均毫秒
}
}
// 使用
double avgMs = Benchmark.Time(() => {
// 待測代碼
}, 1000);
Console.WriteLine($"平均耗時: {avgMs:F4} ms");
Stopwatch 是 .NET 開發者進行微基準測試的基石工具。掌握其精度來源、屬性選擇、預熱與多次取樣等技巧,能讓效能分析從「感覺慢」進化為「數據驅動的優化」。