目录
- 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);
}
}