c#耗时及性能监测
c#耗时及性能监测
在编程中,我们经常需要测量代码的执行时间,以便评估代码的性能和效率
命名空间 using System.Diagnostics;
字段 | 字段说明 |
---|---|
Frequency | 获取以每秒刻度数表示的计时器频率。此字段为只读。 |
IsHighResolution | 指示计时器是否基于高分辨率性能计数器。 此字段为只读。 |
属性 | 属性说明 |
---|---|
Elapsed | 获取当前实例测量得出的总运行时间。 |
ElapsedMilliseconds | 获取当前实例测量得出的总运行时间(以毫秒为单位)。 |
ElapsedTicks | 获取当前实例测量得出的总运行时间(用计时器刻度表示)。 |
IsRunning | 获取一个值,该值表示 Stopwatch 计时器是否正在运行。 |
方法 | 方法说明 |
---|---|
Equals(Object) | 确定指定对象是否等于当前对象。 |
GetHashCode() | 作为默认哈希函数。 |
GetTimestamp() | 获取计时器机制中的当前刻度数。 |
GetType() | 获取当前实例的 Type。 |
MemberwiseClone() | 创建当前 Object 的浅表副本。 |
Reset() | 停止时间间隔测量,并将运行时间重置为零。 |
Restart() | 停止时间间隔测量,将运行时间重置为零,然后开始测量运行时间。 |
Start() | 开始或继续测量某个时间间隔的运行时间。 |
StartNew() | 初始化新的 Stopwatch 实例,将运行时间属性设置为零,然后开始测量运行时间。 |
Stop() | 停止测量某个时间间隔的运行时间。 |
ToString() | 返回表示当前对象的字符串。 |
基础示例
Stopwatch
类相关字段、属性、方法的使用示例,可以参考代码如下,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
//创建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();
//开始计时
sw.Start();
System.Threading.Thread.Sleep(1000); //耗时操作 测试代码,休眠1000毫秒
//结束计时
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //输出:消耗的毫秒
Console.WriteLine(sw.Elapsed.ToString()); //输出:时:分:秒
//重置秒表
sw.Reset();
Console.WriteLine("Reset End");
//再次开始计时,或者直接用**Restart**函数直接重置并开始
sw.Start();
System.Threading.Thread.Sleep(1200);
//第二次计时结束
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
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.ToString());
}
}
}
实现测量代码块执行时间的封装
创建MeasureDuration.cs,并实现 IDisposable
接口的
using System;
using System.Diagnostics;
namespace MechTE_480.Util
{
/// <summary>
/// 定义了一个名为MeasureDuration的类,用于测量代码的执行时间。该类实现了IDisposable接口,以便在代码块结束时自动释放资源。
/// </summary>
public class MeasureDuration : IDisposable
{
private readonly Stopwatch _stopwatch;
private readonly Action<TimeSpan> _callback;
/// <summary>
/// 构造函数接受一个Action<TimeSpan>类型的回调函数作为参数。在构造函数中,我们将回调函数赋值给私有字段_callback,并使用Stopwatch.StartNew()方法启动一个新的计时器。
/// </summary>
/// <param name="callback"></param>
public MeasureDuration(Action<TimeSpan> callback)
{
_callback = callback;
_stopwatch = Stopwatch.StartNew();
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
_stopwatch.Stop();
_callback(_stopwatch.Elapsed);
}
}
}
在单元测试中使用 MeasureDuration
类来测量代码块的执行时间
[Fact]
public void Duration()
{
using(new MeasureDuration(duration => _msg.WriteLine($ "代码执行时间:{duration}")))
{
// 在这里编写需要测量执行时间的代码
for(int i = 0; i < 10; i++)
{
// 一些耗时的操作
Thread.Sleep(1000);
}
}
}
使用了using语句来创建一个MeasureDuration对象,并在代码块结束时自动释放资源。在MeasureDuration的构造函数中,我们传入了一个回调函数,该函数将在代码块结束时被调用,并将代码执行的时间间隔作为参数传递给回调函数。在回调函数中,我们将代码执行的时间间隔输出到控制台。