30.CSharp的Stopwatch类计时

30.性能优化-CPU-脚本-计时判断代码执行效率-CSharp的Stopwatch类


30.1 知识点

C#的Stopwatch类

Stopwatch 是 C# 提供的高精度计时工具类,属于命名空间 **System.Diagnostics**(诊断)。它可以精确测量代码执行时间,常用于性能分析和调试,提供毫秒甚至微秒级精度。

常用 API:

  1. Stopwatch.StartNew() — 静态方法,返回一个已开始计时的 Stopwatch 对象。
  2. Stop() — 通过计时对象调用,停止计时。
  3. ElapsedMilliseconds — 获取已耗时(毫秒),类型 long,不适合小于 1ms 的测量。
  4. Elapsed.TotalMilliseconds — 获取已耗时(毫秒),类型 double,可精确到微秒级。
  5. Restart() — 清零并重新开始计时。

示例:从开始到结束的完整流程。

using System.Diagnostics;

// 1. 创建并开始计时
Stopwatch stopwatch = Stopwatch.StartNew();

// 2. 执行要测的逻辑
// ... 你的代码 ...

// 3. 停止计时
stopwatch.Stop();

// 4. 获取耗时(毫秒,long,整数)
long msLong = stopwatch.ElapsedMilliseconds;

// 5. 获取耗时(毫秒,double,可到微秒级)
double msDouble = stopwatch.Elapsed.TotalMilliseconds;

// 若需再次计时,可 Restart
// stopwatch.Restart();

利用C#机制封装一个计时类

与上一篇「Unity 的 Time 类」类似,可以用 C# 的 using 语句块 + IDisposable 封装一个计时类:构造时用 Stopwatch.StartNew() 开始计时,DisposeStop() 并用 Elapsed.TotalMilliseconds 得到毫秒级(甚至微秒级)耗时,再输出总耗时和平均每次耗时。这样写法简洁,且不会漏掉结束计时。

实现:下面 CustomTimer 使用 Stopwatch 替代 Time.realtimeSinceStartup,在 Dispose 中通过 Elapsed.TotalMilliseconds 得到更精确的耗时(double,可到微秒级)。

using UnityEngine;
using System;
using System.Diagnostics;

public class CustomTimer : IDisposable
{
    private string _name;   // 计时任务的名字
    private uint _num;      // 执行次数
    private Stopwatch _watch;

    public CustomTimer(string name, uint num)
    {
        _name = name;
        _num = num;
        if (_num == 0) _num = 1;
        _watch = Stopwatch.StartNew();  // 创建并开始计时
    }

    public void Dispose()
    {
        _watch.Stop();
        double spendTime = _watch.Elapsed.TotalMilliseconds;  // 微秒级精度
        Util.Log(string.Format("{0}计时结束,共耗时{1}ms,一共测试{2}次,每次平均耗时{3}ms",
            _name, spendTime, _num, spendTime / _num));
    }
}

使用方式:用 using 包裹要测的逻辑;离开作用域时自动调用 Dispose 并打印结果。建议在消耗稳定后通过按键等触发,而不是在 Start 里直接跑。

uint num = 10000;
using (new CustomTimer("Debug耗时测试", num))
{
    for (int i = 0; i < num; i++)
    {
        // 换成自己要测的函数或代码逻辑
        Debug.Log("123123");
    }
}

运行后,控制台会输出类似:「Debug耗时测试计时结束,共耗时 xxx ms,一共测试 10000 次,每次平均耗时 x.xx ms」


30.2 知识点代码

Lesson30_性能优化_CPU_脚本_计时判断代码执行效率_CSharp的Stopwatch类.cs

using UnityEngine;

public class Lesson30_性能优化_CPU_脚本_计时判断代码执行效率_CSharp的Stopwatch类 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 C#的Stopwatch类

        /*
         * Stopwatch 属于 System.Diagnostics,高精度计时,毫秒/微秒级。
         * 常用:StartNew() 开始计时,Stop() 停止,ElapsedMilliseconds(long)、Elapsed.TotalMilliseconds(double),Restart() 清零重启。
         */

        #endregion

        #region 知识点二 利用C#机制封装一个计时类

        /* 使用 using 语句块 + IDisposable,构造时 Stopwatch.StartNew(),Dispose 时 Stop() 并用 Elapsed.TotalMilliseconds 输出 */

        #endregion
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            uint num = 10000;
            using (new CustomTimer("Debug耗时测试", num))
            {
                for (int i = 0; i < num; i++)
                {
                    Debug.Log("123123");
                }
            }
        }
    }
}

CustomTimer.cs(基于 Stopwatch 的计时封装)

using UnityEngine;
using System;
using System.Diagnostics;

public class CustomTimer : IDisposable
{
    // 计时任务的名字
    private string _name;

    // 计时任务的执行次数
    private uint _num;

    // 计时对象
    private Stopwatch _watch;

    public CustomTimer(string name, uint num)
    {
        _name = name;
        _num = num;
        // 避免传入次数传错,如果为 0 至少执行 1 次
        if (_num == 0)
            _num = 1;
        // 声明一个计时对象并直接开始计时
        _watch = Stopwatch.StartNew();
    }

    public void Dispose()
    {
        _watch.Stop();
        // 得到微秒级精度的时间(double,毫秒带小数)
        double spendTime = _watch.Elapsed.TotalMilliseconds;
        Util.Log(string.Format("{0}计时结束,共耗时{1}ms,一共测试{2}次,每次平均耗时{3}ms",
            _name, spendTime, _num, spendTime / _num));
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏