目录
- C# Stopwatch的使用
- 什么是Stopwatch
- Stopwatch的简单使用
- C#使用Stopwatch精确测量运行时间
- 测量耗时操作的运行时间
- 查看Stopwatch计时器的计时方式
- 附上官网上的一个测试实例
- 总结
C# Stopwatch的使用
什么是Stopwatch
Stopwatch:提供一组方法和属性,可以准确的测量运行时间。
使用的时候需要引用命名空间:System.Diagnostics。
Stopwatch的简单使用
//创建Stopwatch实例 | |
Stopwatch sw = new Stopwatch(); | |
//开始计时 | |
sw.Start(); | |
for (int i = 0; i < 100; i++) | |
{ | |
Console.WriteLine(i); | |
} | |
//停止计时 | |
sw.Stop(); | |
Console.WriteLine("用时:" + sw.ElapsedMilliseconds + ""); | |
//重置 停止时间间隔测量,并将运行时间重置为0 | |
sw.Reset(); | |
Console.WriteLine("用时:" + sw.ElapsedMilliseconds + ""); | |
//重启 停止时间间隔测量,并将运行时间重置为0,然后重新开始测量运行时间 | |
sw.Restart(); | |
for (int i = 0; i < 100; i++) | |
{ | |
Console.WriteLine(i); | |
} | |
sw.Stop(); | |
//获取当前实例测量得出的总运行时间(以毫秒为单位) | |
Console.WriteLine("用时:" + sw.ElapsedMilliseconds + ""); | |
//获取当前实例测量得出的总运行时间 | |
Console.WriteLine("用时:"+sw.Elapsed); | |
//获取当前实例测量得出的总运行时间(用计时器刻度表示)。 | |
Console.WriteLine(sw.ElapsedTicks); | |
Console.Read(); | |
//使用StartNew,相当于已经实例化并且启动计时 | |
Stopwatch sw=Stopwatch.StartNew(); | |
for (int i = 0; i < 100; i++) | |
{ | |
Console.WriteLine(i); | |
} | |
sw.Stop(); | |
//获取当前实例测量得出的总运行时间(以毫秒为单位) | |
Console.WriteLine("用时:" + sw.ElapsedMilliseconds + ""); | |
//获取当前实例测量得出的总运行时间 | |
Console.WriteLine("用时:"+sw.Elapsed); | |
Console.Read(); |
C#使用Stopwatch精确测量运行时间
一般测量时间间隔使用的是DateTime.Now实例的DateTime.Ticks当前属性,想要精确测量一个操作的运行时间就只能使用Stopwatch类计时了。
Stopwatch计时精度取决于硬件,如果安装的硬件和操作系统支持高分辨率性能计数器, 则Stopwatch类将使用该计数器来测量运行时间。否则,Stopwatch类将使用系统计时器来测量运行时间。
测量耗时操作的运行时间
Stopwatch stopWatch = new Stopwatch(); | |
stopWatch.Start(); | |
Thread.Sleep(5000); // 耗时操作 | |
stopWatch.Stop(); | |
// 将经过的时间作为TimeSpan值 | |
TimeSpan ts = stopWatch.Elapsed; | |
// 格式和显示时间值 | |
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}-{4:000}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds, (ts.Ticks * 100 / 1000)%1000); | |
Console.WriteLine("RunTime " + elapsedTime); | |
// 将经过的时间作为毫秒数 | |
long mSeconds = stopWatch.ElapsedMilliseconds; | |
Console.WriteLine("RunTime(ms) " + mSeconds); | |
// 获取经过时间的计时器刻度 | |
// 也可在耗时操作前后使用Stopwatch.GetTimestamp()各获取1个Ticks值,然后相减得到耗时操作花费的计时器刻度 | |
// 计时器采用的计时方式不同,tick的时间单位不同 | |
long tick = stopWatch.ElapsedTicks; | |
Console.WriteLine("RunTime(tick) " + tick); | |
if (Stopwatch.IsHighResolution) | |
{ | |
// 计时器刻度是高性能计时器滴答数 | |
Console.WriteLine("使用系统高分辨率性能计数器计时:"); | |
Console.WriteLine(" RunTime(ns) " +tick* ((1000L * 1000L * 1000L)/ Stopwatch.Frequency)); | |
} | |
else | |
{ | |
// 计时器刻度是DateTime.Now实例的DateTime.Ticks当前属性 | |
Console.WriteLine("使用DateTime类计时:"); | |
Console.WriteLine(" RunTime(ns) " + tick * 100); | |
} |
查看Stopwatch计时器的计时方式
/// <summary> | |
/// 显示计时器属性 | |
/// </summary> | |
public static void DisplayTimerProperties() | |
{ | |
// 显示定时器频率和分辨率 | |
if (Stopwatch.IsHighResolution) | |
{ | |
Console.WriteLine("操作使用系统高分辨率性能计数器计时"); | |
} | |
else | |
{ | |
Console.WriteLine("操作使用DateTime类计时"); | |
} | |
long frequency = Stopwatch.Frequency; | |
Console.WriteLine(" 计时器频率,单位为每秒滴答数 = {0}", | |
frequency); | |
long nanosecPerTick = (1000L * 1000L * 1000L) / frequency; | |
Console.WriteLine(" 计时器分辨率为 {0} 纳秒/滴答", | |
nanosecPerTick); | |
} |
附上官网上的一个测试实例
private static void TimeOperations() | |
{ | |
long nanosecPerTick = (1000L * 1000L * 1000L) / Stopwatch.Frequency; | |
const long numIterations = 10000; | |
// 定义操作标题名称 | |
String[] operationNames = {"操作: Int32.Parse(\"0\")", | |
"操作: Int32.TryParse(\"0\")", | |
"操作: Int32.Parse(\"a\")", | |
"操作: Int32.TryParse(\"a\")"}; | |
Console.WriteLine(); | |
Console.WriteLine("注:1ticks=100ns,1s=1000ms,1ms=1000us,1us=1000ns"); | |
// 从字符串解析整数的四种不同实现 | |
for (int operation = 0; operation <= 3; operation++) | |
{ | |
// 定义操作统计的变量 | |
long numTicks = 0; | |
long numRollovers = 0; | |
long maxTicks = 0; | |
long minTicks = Int64.MaxValue; | |
int indexFastest = -1; | |
int indexSlowest = -1; | |
long milliSec = 0; | |
Stopwatch time10kOperations = Stopwatch.StartNew(); | |
// 运行当前操作10001次。 | |
// 第一次执行时间将被丢弃,因为它可能会扭曲平均时间。 | |
for (int i = 0; i <= numIterations; i++) | |
{ | |
long ticksThisTime = 0; | |
int inputNum; | |
Stopwatch timePerParse; | |
switch (operation) | |
{ | |
case 0: | |
// 使用try-catch语句分析有效整数 | |
// 启动新的秒表计时器 | |
timePerParse = Stopwatch.StartNew(); | |
try | |
{ | |
inputNum = Int32.Parse("0"); | |
} | |
catch (FormatException) | |
{ | |
inputNum = 0; | |
} | |
// 停止计时器,并保存操作所用的计时ticks | |
timePerParse.Stop(); | |
ticksThisTime = timePerParse.ElapsedTicks; | |
break; | |
case 1: | |
timePerParse = Stopwatch.StartNew(); | |
if (!Int32.TryParse("0", out inputNum)) | |
{ | |
inputNum = 0; | |
} | |
timePerParse.Stop(); | |
ticksThisTime = timePerParse.ElapsedTicks; | |
break; | |
case 2: | |
timePerParse = Stopwatch.StartNew(); | |
try | |
{ | |
inputNum = Int32.Parse("a"); | |
} | |
catch (FormatException) | |
{ | |
inputNum = 0; | |
} | |
timePerParse.Stop(); | |
ticksThisTime = timePerParse.ElapsedTicks; | |
break; | |
case 3: | |
timePerParse = Stopwatch.StartNew(); | |
if (!Int32.TryParse("a", out inputNum)) | |
{ | |
inputNum = 0; | |
} | |
timePerParse.Stop(); | |
ticksThisTime = timePerParse.ElapsedTicks; | |
break; | |
default: | |
break; | |
} | |
// 跳过第一个操作的时间,以防它导致一次性性能下降。 | |
if (i == 0) | |
{ | |
time10kOperations.Reset(); | |
time10kOperations.Start(); | |
} | |
else | |
{ | |
// 更新迭代1-10001的操作统计信息。 | |
if (maxTicks < ticksThisTime) | |
{ | |
indexSlowest = i; | |
maxTicks = ticksThisTime; | |
} | |
if (minTicks > ticksThisTime) | |
{ | |
indexFastest = i; | |
minTicks = ticksThisTime; | |
} | |
numTicks += ticksThisTime; | |
if (numTicks < ticksThisTime) | |
{ | |
// Keep track of rollovers. | |
numRollovers++; | |
} | |
} | |
} | |
// 显示10000次迭代的统计信息 | |
time10kOperations.Stop(); | |
milliSec = time10kOperations.ElapsedMilliseconds; | |
Console.WriteLine(); | |
Console.WriteLine("{0} 统计:", operationNames[operation]); | |
Console.WriteLine(" 最慢时间: 第{0}/{1}次操作,时间为{2} ticks", | |
indexSlowest, numIterations, maxTicks); | |
Console.WriteLine(" 最快时间: 第{0}/{1}次操作,时间为{2} ticks", | |
indexFastest, numIterations, minTicks); | |
Console.WriteLine(" 平均时间: {0} ticks = {1} ns", | |
numTicks / numIterations, | |
(numTicks * nanosecPerTick) / numIterations); | |
Console.WriteLine(" {0} 次操作的总时间: {1} ms", | |
numIterations, milliSec); | |
} | |
} |