文章目錄
Stopwatch 的正確用法
前幾天從 Cash 大的粉專上看到 Cash Wu Geek 分享了 youtuber-Nick Chapsas 對於 Stopwatch
的正確用法:Youtube:How to Measure Time Correctly in .NET,覺得值得仔細了解一下,快速筆記一下心得。
.NET 7 開始提供了 Stopwatch
的新 api:GetTimestamp
透過 Diagnostics
命名空間提供的,可以幫助我們更容易地使用 Stopwatch
來計算程式碼的執行時間。
基本環境說明
- macOS Sequoia 15.0.1 (Apple M2 Pro)
- dotnet sdk 7.0.410
- dotnet sdk 8.0.401
- dotnet sdk 9.0.100
- JetBrains Rider 2024.3
NuGet package
- BenchmarkDotNet 0.14.0
使用方式
.NET 6 之前的用法
Stopwatch stopwatch = Stopwatch.StartNew(); // 執行程式碼 Console.WriteLine($"Elapsed time: {stopwatch.Elapsed}");
.NET 7 新增的 api:
GetTimestamp
- 透過
Stopwatch.GetTimestamp()
取得系統時間 - 使用
Stopwatch.GetElapsedTime(long timestamp)
取得執行時間
long timestamp = Stopwatch.GetTimestamp(); // 執行程式碼 Console.WriteLine($"Elapsed time: {Stopwatch.GetElapsedTime(timestamp)}");
- 透過
心得
新語法的優點:
避免建立新物件而產生的記憶體分配
new Stopwatch()
與Stopwatch.StartNew()
都會額外建立新的 Stopwatch 物件而產生記憶體分配,而這個動作僅是為了衡量程式碼的執行時間,這樣的記憶體分配是不必要的,而新的 API 可以避免這個問題跨平台優化取得系統時間
Stopwatch.GetTimestamp()
可以取得系統時間,而這個時間是跨平台的,這樣可以避免不同平台的時間取得方式不同而造成的問題隨著
GetTimestamp
新增的GetElapsedTime
則提供了簡化處理Stopwatch.Frequency
和TimeSpan.TicksPerSecond
的公式
新舊語法在不同版本的 .NET SDK 效能比較
測試程式碼
測試結果
個別 sdk 的測試結果
.NET 7
.NET 8
.NET 9
可以看到在 .NET 7 與 .NET 8 上
Stopwatch.StartNew
確實存在 memory allocated 的問題,執行速度也存在差異,但 .NET 9 就沒看到Stopwatch.StartNew
memory allocated 與執行速度差異的現象,我粗略查了一下官方文件沒有發現有針對 Stopwatch 效能提升的介紹說明,看了 IL code 新舊語法也確實不同,我再找時間翻翻 source code,有找到再補充。
參考資訊
文章作者 Yowko Tsai
上次更新 2024-11-22
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。