C#中Stopwatch的使用及说明
作者:TheWindofFate
这篇文章主要介绍了C#中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); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。