C#中Stopwatch類實現(xiàn)精確代碼執(zhí)行時間測量的兩種方案
C#中Stopwatch類實現(xiàn)精確代碼執(zhí)行時間測量
在C#開發(fā)中,精確測量代碼執(zhí)行時間對于性能優(yōu)化和算法對比至關(guān)重要。本文將介紹如何使用System.Diagnostics.Stopwatch類實現(xiàn)高精度的執(zhí)行時間測量,并提供基礎(chǔ)用法和進階實現(xiàn)兩種方案。
基礎(chǔ)Stopwatch用法
Stopwatch類提供了簡單直接的時間測量方式,適用于單次操作耗時分析。
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
var stopwatch = Stopwatch.StartNew();
// 模擬耗時操作
for (int i = 0; i < 1000000; i++) { }
stopwatch.Stop();
Console.WriteLine($"基礎(chǔ)用法 - 執(zhí)行時間: {stopwatch.ElapsedMilliseconds}ms");
Console.WriteLine($"精確時間: {stopwatch.Elapsed.TotalSeconds:F6}秒");
}
}關(guān)鍵API說明:
StartNew():創(chuàng)建并立即啟動計時器Stop():停止計時ElapsedMilliseconds:獲取毫秒級耗時Elapsed.TotalSeconds:獲取精確到秒的小數(shù)
進階計時器實現(xiàn)
對于需要多次測量和統(tǒng)計平均值的場景,可以封裝CodeTimer類實現(xiàn)更復(fù)雜的功能。
using System;
using System.Collections.Generic;
using System.Diagnostics;
class CodeTimer
{
private Stopwatch _stopwatch = new Stopwatch();
private Queue<long> _timeRecords = new Queue<long>();
private long _totalTime;
private const int MaxRecords = 10;
public double AverageTimeMs => _timeRecords.Count > 0 ? _totalTime / (double)_timeRecords.Count : 0;
public void Start()
{
_stopwatch.Restart();
}
public void StopAndPrint(string operationName)
{
_stopwatch.Stop();
long elapsedMs = _stopwatch.ElapsedMilliseconds;
_timeRecords.Enqueue(elapsedMs);
_totalTime += elapsedMs;
if (_timeRecords.Count > MaxRecords)
{
_totalTime -= _timeRecords.Dequeue();
}
Console.WriteLine($"{operationName}: {elapsedMs}ms");
}
}進階功能:
- 自動計算多次執(zhí)行的平均時間
- 滑動窗口統(tǒng)計(默認保留最近10次記錄)
- 方便的打印輸出功能
兩種方案對比
| 特性 | 基礎(chǔ)方案 | 進階方案 |
|---|---|---|
| 適用場景 | 單次操作耗時分析 | 多次執(zhí)行統(tǒng)計/性能趨勢分析 |
| 功能復(fù)雜度 | 低 | 高 |
| 內(nèi)存占用 | 極低 | 中等(存儲歷史記錄) |
| 輸出信息 | 原始時間數(shù)據(jù) | 格式化輸出+統(tǒng)計值 |
最佳實踐建議
- 測量環(huán)境準備:
- 關(guān)閉其他占用CPU的程序
- 在Release模式下運行
- 預(yù)熱代碼(首次運行可能較慢)
- 測量精度控制:
- 避免在測量代碼中包含I/O操作
- 測量足夠長的操作(>1ms)
- 多次測量取平均值
- 結(jié)果分析:
- 關(guān)注時間變化趨勢而非絕對值
- 對比不同實現(xiàn)時使用相同測試環(huán)境
- 記錄測試時的系統(tǒng)負載情況
以下內(nèi)容為補充知識,需要的朋友拿去用。
C# 減少代碼運行時間的7 個實戰(zhàn)技巧
前言
想象一下,你正在一家忙碌的咖啡館里工作,顧客絡(luò)繹不絕,你不停地跑前跑后,累得直喘氣。
如果你能同時準備幾杯咖啡,效率是不是會大大提高?
這就是并發(fā)編程的魅力所在。
今天,我們就來聊聊 C# 中的 Task,看看它是如何幫助我們在代碼中實現(xiàn)“多任務(wù)并行”的奇跡。
1. Task.Run:簡單高效的啟動方式
// 使用 Task.Run 來快速啟動一個后臺任務(wù)
Task.Run(() =>
{
Console.WriteLine($"任務(wù)運行在線程 {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(1000); // 模擬耗時操作
Console.WriteLine("任務(wù)完成!");
});解釋:這是最常用的啟動異步任務(wù)的方法,適合執(zhí)行一些不需要立即返回結(jié)果的操作。
2. Task.Factory.StartNew:靈活應(yīng)對各種需求
// 使用 Task.Factory.StartNew 來處理長時間運行的任務(wù)
Task.Factory.StartNew(() =>
{
Console.WriteLine($"任務(wù)運行在線程 {Thread.CurrentThread.ManagedThreadId}");
// 模擬CPU密集型計算
for (int i = 0; i < 1000000; i++) {}
}, TaskCreationOptions.LongRunning); // 提示這是一個長任務(wù)提示:對于需要較長時間才能完成的任務(wù),這種方式可以提供更多的控制選項。
3. new Task:手動管理任務(wù)
var task = new Task(() =>
{
Console.WriteLine($"任務(wù)運行在線程 {Thread.CurrentThread.ManagedThreadId}");
File.WriteAllText("test.txt", "Hello Task!");
});
task.Start(); // 需要手動啟動任務(wù)注意:雖然這種方法提供了對任務(wù)生命周期的完全控制,但在大多數(shù)情況下,推薦使用更簡便的方式。
4. 多任務(wù)并行處理
var tasks = new List<Task>();
for (int i = 0; i < 5; i++)
{
int taskId = i; // 避免閉包陷阱
tasks.Add(Task.Run(() =>
{
Console.WriteLine($"任務(wù){(diào)taskId}開始執(zhí)行");
Thread.Sleep(1000 * (taskId + 1));
Console.WriteLine($"任務(wù){(diào)taskId}完成");
}));
}
await Task.WhenAll(tasks); // 等待所有任務(wù)完成
Console.WriteLine("所有任務(wù)都完成了!");小貼士:合理利用多任務(wù)并行處理,可以大幅縮短程序的執(zhí)行時間。
5. 帶返回值的任務(wù)
Task<int> fibonacciTask = Task.Run(() =>
{
int Fib(int n) => n <= 1 ? n : Fib(n - 1) + Fib(n - 2);
return Fib(35); // 計算斐波那契數(shù)列第35項
});
Console.WriteLine("正在拼命計算中...");
int result = await fibonacciTask;
Console.WriteLine($"計算結(jié)果: {result}");亮點:通過返回值,你可以輕松地在異步任務(wù)完成后獲取其結(jié)果。
6. 任務(wù)鏈式調(diào)用
Task.Run(() =>
{
Console.WriteLine("第一階段:數(shù)據(jù)準備");
return"原始數(shù)據(jù)";
})
.ContinueWith(previousTask =>
{
Console.WriteLine($"第二階段:處理 {previousTask.Result}");
return$"處理后的-{previousTask.Result}";
})
.ContinueWith(previousTask =>
{
Console.WriteLine($"第三階段:存儲 {previousTask.Result}");
File.WriteAllText("data.txt", previousTask.Result);
});好處:鏈式調(diào)用不僅能讓代碼看起來更整潔,還能確保各階段按順序執(zhí)行。
總結(jié)
恭喜你,現(xiàn)在你應(yīng)該已經(jīng)掌握了使用 Task 進行多線程編程的基礎(chǔ)知識和一些高級技巧。
記住,實踐是檢驗真理的唯一標準。
到此這篇關(guān)于C#中Stopwatch類實現(xiàn)精確代碼執(zhí)行時間測量的兩種方案的文章就介紹到這了,更多相關(guān)C# Stopwatch類代碼執(zhí)行時間測量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
HighCharts圖表控件在ASP.NET WebForm中的使用總結(jié)(全)
這篇文章主要介紹了HighCharts圖表控件在ASP.NET WebForm中的使用總結(jié)(全),需要的朋友可以參考下2015-08-08
C# List實現(xiàn)行轉(zhuǎn)列的通用方案
本篇通過行轉(zhuǎn)列引出了System.Linq.Dynamic,并且介紹了過濾功能,具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03
輕松學(xué)習(xí)C#的結(jié)構(gòu)和類
輕松學(xué)習(xí)C#的結(jié)構(gòu)和類,對C#的結(jié)構(gòu)和類感興趣的朋友可以參考本篇文章,幫助大家更靈活的運用C#的結(jié)構(gòu)和類2015-11-11
DevExpress獲取節(jié)點下可視區(qū)域子節(jié)點集合的實現(xiàn)方法
這篇文章主要介紹了DevExpress獲取節(jié)點下可視區(qū)域子節(jié)點集合的實現(xiàn)方法,是C#程序設(shè)計中較為常見的技巧,需要的朋友可以參考下2014-08-08

