「Unity」时间记录小工具

前言

  • 原创文章,转载请标明出处,谢谢!

这是什么

这是一个在Unity中,用以记录某个代码行为运行时间的小工具。效果如下图所示,它们分别展示了:

  • 一次任务的记录
  • 嵌套任务的记录(记录中嵌套记录)
  • 递归任务的记录(套娃)
    一次任务的记录 在这里插入图片描述 在这里插入图片描述

为什么要用它

笔者的毕业设计中要时刻关注一些代码行为的时间消耗。如果使用C#的Stopwatch类,会严重破坏代码结构,并且当如果需要记录一个行为中若干子行为各自时间时(例如函数A包含函数AA、AB,我想要记录这三个函数的时间,并直观得到各部分占A的比例),很难通过Stopwatch达到目的。

因此笔者封装了一个用以记录时间消耗的工具,它具有以下特点:

  • 简单、安全的使用方式,几乎不破坏代码结构,更不会影响执行结果
  • 嵌套记录时,很容易看到一个父行为中各个子行为的时间消耗
  • 通过编辑器扩展,无需通过调试、Log输出等方式查看结果

其他

  • 因为源码中有一定的注释且代码量少,因此代码讲解部分比较简陋。如果你需要详细的的讲解,请使用私信或者评论的方式告诉我,我会进行补全!

使用方法

我要从哪里获取代码

代码和使用示例已经放在了github上,github地址:
UnknownArkish/UnityTimeRecorder

放在你的工程中:

  1. 将 Assets/Scripts/TimeRecorder.cs文件放在你的工程目录中放置脚本文件夹的下;
  2. 将Assets/Editor/TimeRecorderEditor.cs文件放置在你的工程目录的Assets/Editor文件夹下(或Editor中的文件夹,总之目录路径要在Editor中)
  3. 场景中创建一个物体,挂上 TimeRecorder.cs 脚本

使用示例

TimerRecorder中只有一个关于记录时间的函数 Record,其函数原型如下:

public void Record(
	string actionName, 
	Action action, 
	RecordUnit unit = RecordUnit.Millisecond
)
  • string actionName: 行为的名字;
  • Action action: 行为,需要传入一个无参无返回值的函数,也可传入一个 无参无返回值的 lambda表达式;
  • RecordUnit unitOption: 可选参数,行为记录的时间单位。

注意:由于TimeRecorder采用单例模式,因此你需要通过 TimeRecorder.Instance 获取单例实例。

简单记录

大多数情况下,你只需要将需要记录的行为打包成一个lambda表达式作为参数传入即可。如下所示将会记录任务A的执行时间:

TimeRecorder.Instance.Record( 
	"任务A", 
	()=>{
		// 任务A...
	}
);

// 任务B...

// 任务C...

更具体的例子,假设有以下两个任务,一个任务几乎不耗时,一个任务耗时严重(方便起见这里使用循环模拟,也可使用协程):

    // 模拟一项简单的任务,几乎不消耗时间
    private void SimpleFunc() { }
    // 模拟一项繁重的任务,消耗很多时间
    private void HeavyFunc()
    {
        int count = 1000000;
        for (int i = 0; i < count; i++) { }
    }

它们在示例代码中的调用如下:

    private void TestSimpleFunc()
    {
        SimpleFunc();
    }
    private void TestHeavyFunc()
    {
        HeavyFunc();
    }

如果我想知道SampleFunc(或者HeavyFunc)的执行时间,那么只需要更改为如下所示的代码即可:

    private void TestSimpleFunc()
    {
        TimeRecorder.Instance.Record("TestSimpleFunc", () =>
        {
            SimpleFunc();
        });
    }
    private void TestHeavyFunc()
    {
        TimeRecorder.Instance.Record("TestHeavyFunc", () =>
        {
            HeavyFunc();
        });
    }

查看记录

行为的记录结果可以在挂载了 TimeRecorder.cs 脚本的 Inspector 窗口上查看。

如下图所示,当示例程序若干次调用 TestSimpleFuncTestHeavyFunc后,在 Inspector 上所观察到的结果:

在这里插入图片描述

嵌套记录

和简单记录一样,你只需要在想要记录的行为处调用 TimeRecorder.Instance.Record 代码即可。

  • 如果出现了嵌套记录,TimerRecorder会自动处理好它们,你无需担心任何事情。

为了模拟嵌套记录,示例代码中使用了如下代码:
TestEmbeddedFunc中嵌套了刚才的TestSimpleFuncTestHeavyFunc

    // 测试嵌套记录
    private void TestEmbeddedFunc()
    {
        TimeRecorder.Instance.Record("EmbeddedFunc", () =>
        {
            TestSimpleFunc();
            TestHeavyFunc();
        });
    }

运行结果如下图所示,同样的你可以在Inspecotr上查看得到:
在这里插入图片描述

  • 可以很直观的发现TestSimpleFuncTestHeavyFuncTestEmbeddedFunc的子行为,以及它们各自的时间。

递归记录

即便是递归的行为也能正常工作。为了模拟递归,示例代码中使用以下代码:

    // 测试递归记录,参数是递归次数
    private void TestRecursiveFunc(int recursiveTime)
    {
        if (recursiveTime < 1) return;
        TimeRecorder.Instance.Record(
	        string.Format("TestRecursiveFunc_{0}", recursiveTime), 
	        () =>
	        {
	            HeavyFunc();
	            TestRecursiveFunc(recursiveTime - 1);
	        }
        );
    }

运行结果如下图所示(这里递归次数为5):
在这里插入图片描述


代码讲解

由于源代码中已经有一定的注释,而且代码量很少,读者感兴趣的话可以自行阅读:

  • 编辑器扩展部分要求读者有相关的编写经验,除非你需要改动源码,可以否则不需要理解这部分(即TimeRecorderEditor.cs
  • 若你对编辑器扩展感兴趣,可以学习这篇文章(原作者分为了三篇文章,这里只给出第一篇):
  • https://blog.csdn.net/qq_33337811/article/details/61920340
发布了4 篇原创文章 · 获赞 0 · 访问量 452

猜你喜欢

转载自blog.csdn.net/Arkish/article/details/104204540