Unity - 带耗时 begin ... end 的耗时统计的Log - TSLog

news2024/10/5 21:18:11

CSharp Code

// jave.lin 2023/04/21 带 timespan 的日志 (不帶 log hierarchy 结构要求,即: 不带 stack 要求)

using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class TSLog
{
    // ts == time span
    public class WithTimeSpanLogData
    {
        public int idx;
        public string tag;
        public TimeSpan timeSpan; // (DateTime)start - (DateTime)end

        public string startDesc;
        public string endDesc;
        public DateTime startDateTime;
        public DateTime endDateTime;
        public string classNameStart;
        public int lineStart;
        public string classNameEnd;
        public int lineEnd;

        public static string GetCSVTitle()
        {
            return $"编号, 标记, 耗时, 开始描述, 结束描述, 开始时间, 结束时间, 开始文件, 开始行, 结束文件, 结束行\n";
        }

        public override string ToString()
        {
            return $"{idx}, {tag}, {timeSpan}, {startDesc}, {endDesc}, {startDateTime}, {endDateTime}, {classNameStart}, {lineStart}, {classNameEnd}, {lineEnd}";
        }
    }

    // clog == custom log
    public static void CLog(string content)
    {
        Debug.Log($"[{DateTime.Now}] {content}");
    }

    private static void GetCodeLineNum(out string fileName, out int lineNum)
    {
        System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(0, true);
        System.Diagnostics.StackFrame frame = st.GetFrame(st.FrameCount - 1);
        fileName = frame.GetFileName();
        lineNum = frame.GetFileLineNumber();
    }

    //=== DEMO START ======================

    private static void Test()
    {
        System.Threading.Thread.Sleep(2000);
        CLog("Test Func Testing with date time Log");
    }

    private static void Test2()
    {
        System.Threading.Thread.Sleep(1000);
        CLog("Test2 Func Testing with date time Log");
    }

    [MenuItem("实用工具/测试/测试TSLog并写日志结果")]
    private static void Usage()
    {
        var tslog = new TSLog();

        tslog.Clear();

        tslog.BeginTag("Test", "开始Test函数,并标记");
        Test();
        tslog.EndTag("Test", "结束Test函数,并统计消耗");

        tslog.BeginTag("Test2", "开始Test2函数,并标记");
        Test2();
        tslog.EndTag("Test2", "结束Test2函数,并统计耗时");

        tslog.WriteTagLogs();

        /*

        测试输出:

编号, 标记, 耗时, 开始描述, 结束描述, 开始时间, 结束时间, 开始文件, 开始行, 结束文件, 结束行
0, Test, 00:00:02.0112773, 开始Test函数,并标记, 结束Test函数,并统计消耗, 2023/4/21 15:36:10, 2023/4/21 15:36:12, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 73, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 75
1, Test2, 00:00:01.0104517, 开始Test2函数,并标记, 结束Test2函数,并统计耗时, 2023/4/21 15:36:12, 2023/4/21 15:36:13, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 77, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 79


         * */
    }

    //=== DEMO END ======================

    // WTSL ==> With TimeSpan Log
    private int WTSLDataIDXCounter = 0;

    private List<WithTimeSpanLogData> logTag_List = new List<WithTimeSpanLogData>();

    private Dictionary<string, WithTimeSpanLogData> logTag_Dict = new Dictionary<string, WithTimeSpanLogData>();

    public void Clear()
    {
        WTSLDataIDXCounter = 0;
        logTag_List.Clear();
        logTag_Dict.Clear();
    }

    public void BeginTag(string tag, string description = null)
    {
        tag = tag.Replace(",", "_");
        if (description != null)
            description = description.Replace(",", "_");

        var alreadyBeginTag = logTag_Dict.TryGetValue(tag, out var data);
        var nowDateTime = DateTime.Now;
        if (alreadyBeginTag)
        {
            Debug.LogWarning($"[{nowDateTime}] W BeginTag : {tag}, but alreadyBeginTag at time : {data}");
        }
        else
        {
            GetCodeLineNum(out string fileName, out int lineNum);

            Debug.Log($"[{nowDateTime}] D BeginTag : {tag}");
            logTag_Dict[tag] = new WithTimeSpanLogData
            {
                idx = WTSLDataIDXCounter++,
                tag = tag,
                startDesc = description,
                startDateTime = nowDateTime,
                classNameStart = fileName,
                lineStart = lineNum,
            };
        }
    }

    public void EndTag(string tag, string description = null)
    {
        tag = tag.Replace(",", "_");
        if (description != null)
            description = description.Replace(",", "_");

        var hasBeginTag = logTag_Dict.TryGetValue(tag, out var data);
        var nowDateTime = DateTime.Now;
        if (hasBeginTag)
        {
            var ts = nowDateTime - data.startDateTime;
            Debug.Log($"[{nowDateTime}] D EndTag : {tag}, Timespan : {ts}");
            logTag_Dict.Remove(tag);

            GetCodeLineNum(out string fileName, out int lineNum);

            data.endDesc = description;
            data.endDateTime = nowDateTime;
            data.classNameEnd = fileName;
            data.lineEnd = lineNum;
            data.timeSpan = ts;

            logTag_List.Add(data);
        }
        else
        {
            Debug.LogWarning($"[{nowDateTime}] W EndTag : {tag}, have no Timespan");
        }
    }

    public bool WriteTagLogs()
    {
        var ret = false;
        var error = string.Empty;
        try
        {
            using (var streamWriter = new StreamWriter("BuildingTagLogs.csv", false))
            {
                // 标题
                streamWriter.Write(WithTimeSpanLogData.GetCSVTitle());

                // 内容

                var list = logTag_List;
                list.Sort((a, b) => a.idx - b.idx);

                foreach (var data in list)
                {
                    streamWriter.Write($"{data}\n");
                }

                streamWriter.Close();
            }
            Debug.Log("WriteTagLogs : BuildingTagLogs.csv Successfully!");

            ret = true;
            error = string.Empty;
        }
        catch (System.Exception er)
        {
            ret = false;
            error = er.ToString();
        }
        finally
        {
            if (!ret)
            {
                Debug.LogError($"WriteTagLogs : BuildingTagLogs.csv Failured, error : {error}");
            }
        }
        return ret;
    }
}

CSV Output

编号, 标记, 耗时, 开始描述, 结束描述, 开始时间, 结束时间, 开始文件, 开始行, 结束文件, 结束行
0, Test, 00:00:02.0112773, 开始Test函数,并标记, 结束Test函数,并统计消耗, 2023/4/21 15:36:10, 2023/4/21 15:36:12, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 73, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 75
1, Test2, 00:00:01.0104517, 开始Test2函数,并标记, 结束Test2函数,并统计耗时, 2023/4/21 15:36:12, 2023/4/21 15:36:13, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 77, C:\SuoguoProject\Client\Assets\Editor\TSLog.cs, 79

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/443832.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt 学生信息数据库管理

1 添加样式表 我们采用了样式表 通过添加Qt resources文件 添加前缀 添加文件&#xff0c;将我们的图标进行添加 2 拖动部件 用到的部件 Label 标签Pushbutton 按钮table view 视图LineEdit 输入框 3 程序编写 1 配置sql环境 在 pro文件中 添加 连接数据库跟访问数据…

Qt模型视图结构

一.模型视图介绍 1.Model/View(模型/视图结构) 视图(View)是显示和编辑数据的界面组件&#xff0c; 模型(Model)是视图和原始数据之间的接口 2.视图组件有:QListView QTreeView QTableView&#xff0c;QColumnView&#xff0c;QHeaderView 模型组件有:QStringListM…

MyBatis详解(2)

8、自定义映射resultMap 8.1、resultMap处理字段和属性的映射关系 若字段名和实体类中的属性名不一致&#xff0c;则可以通过resultMap设置自定义映射 <!--resultMap&#xff1a;设置自定义映射属性&#xff1a;id&#xff1a;表示自定义映射的唯一标识type&#xff1a;查询…

PCIE_DMA实例二:xapp1052的EDK仿真

目录 一&#xff1a;前言 二&#xff1a;前期准备 三&#xff1a;操作步骤 四&#xff1a;仿真结果 五&#xff1a;总结 一&#xff1a;前言 对于有的同学&#xff0c;想要学习基于FPGA的PCIe DMA控制器设计&#xff0c;但是手上没有合适的Xilinx开发板&#xff0c;而且xap…

ETCD(五)写请求执行过程

写请求过程 客户端执行写请求指令 etcdctl put hello world —endpoints 192.168.1.1:12379执行流程&#xff1a; 首先客户端通过负载均衡选择一个etcd节点发起gRPC put方法调用&#xff1b;服务器收到请求后经过gRPC拦截器、Quota模块校验&#xff0c;进入KV Server模块&am…

「物联网时代的新选择」漫途科技推出装配式物联网服务,轻松实现项目落地

随着物联网技术的不断发展&#xff0c;越来越多的企业开始重视物联网系统的应用。然而&#xff0c;在物联网时代&#xff0c;鱼龙混杂&#xff0c;小品牌厂商层出不穷&#xff0c;质量参差不齐&#xff0c;这为系统集成商寻找靠谱的供应商伙伴带来了极大的挑战。 一、如何找靠谱…

Nacos配置中心的配置是怎么加载到spring容器的?

首先看到 org.springframework.boot.SpringApplication#applyInitializers 这个方法。 protected void applyInitializers(ConfigurableApplicationContext context) {for (ApplicationContextInitializer initializer : getInitializers()) {Class<?> requiredType G…

单链表C语言实现

链表就是许多节点在逻辑上串起来的数据存储方式 是通过结构体中的指针将后续的节点串联起来 typedef int SLTDataType;//数据类型 typedef struct SListNode//节点 {SLTDataType data;//存储的数据struct SListNode* next;//指向下一个节点地址的指针 }SLTNode;//结构体类型的…

设计模式(GOF)之我见(0)——UML

这里直接梳理画类图时的几个类关系。 类图的语法和功能 关系说明举例依赖&#xff08;Dependency) 偶然的&#xff0c;陌生的。 对类B进行修改会影响到A。 例如&#xff1a;问路时&#xff0c;路人甲给路人乙带路&#xff0c;路人甲的指引必然会影响到路人乙&#xff0c;但是…

在ROS2中使用奥比中光(ORBBEC)的AstraPro深度相机

0.效果演示 1.下载SDK 到官网下载OpenNI2_SDK 记得是下载这个OpenNI2_SDK,而不是下载那个Orbbec_SDK. 2.拷贝至自定义目录 拷贝到你的ubuntu的一个文件夹中&#xff0c;并解压得到 ros2_astra_camera 文件夹 然后新建一个ros2_ws文件夹&#xff0c;再在ros2_ws文件夹中新建…

矩阵链相乘的乘法次数(动态规划)

Description 设 A1, A2, …, An 为矩阵序列&#xff0c;Ai 是阶为 Pi − 1 * Pi 的矩阵 i  1, 2, …, n.试确定矩阵的乘法顺序&#xff0c;使得计算 A1A2…An 过程中元素相乘的总次数最少.Input 多组数据第一行一个整数 n(1≤n≤300) &#xff0c;表示一共有 n 个矩…

真题详解(计算机知识)-软件设计(五十四)

真题详解&#xff08;归并&#xff09;-软件设计&#xff08;五十三)https://blog.csdn.net/ke1ying/article/details/130254861 若无条件转移汇编指令采用直接寻址&#xff0c;则该指令功能是将指令中的地址码送入_____? PC&#xff08;程序计数器&#xff09; 程序计数器&…

10种黑客类型,你知道几种?

黑客一般有 10 种类型 1、白帽黑客 白帽黑客是指通过实施渗透测试&#xff0c;识别网络安全漏洞&#xff0c;为政府及组织工作并获得授权或认证的黑客。他们也确保保护免受恶意网络犯罪。他们在政府提供的规章制度下工作&#xff0c;这就是为什么他们被称为道德黑客或网络安全…

Kyligence Zen 产品体验 --- 初识庐山真面目

简介 Kyligence Zen 是一款数据分析工具&#xff0c;其市场定位是一站式云端指标平台。它基于 Kyligence 核心 OLAP&#xff08;On-Line Analytical Processing&#xff09; 能力打造&#xff0c;提供集业务模型、指标管理、指标加工、数据服务于一体的一站式服务。 其基本的…

Linux: SPI 驱动

文章目录 1. 前言2. SPI 总线驱动2.1 SPI 总线拓扑2.2 SPI 总线工作模式2.3 SPI 总线驱动编写 3. SPI 从设驱动4. SPI 用户空间接口4.1 创建 SPI 总线用户空间字符设备节点4.2 操作 SPI 总线用户字符设备节点 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0…

百趣代谢组学分享,三阴性乳腺癌铁死亡异质性的揭示

百趣代谢组学分享文章标题&#xff1a;Ferroptosis heterogeneity in triple-negative breast cancer reveals an innovative immunotherapy combination strategy 发表期刊&#xff1a;Cell Metabolism 影响因子&#xff1a;31.373 作者单位&#xff1a;复旦大学附属肿瘤医…

DFS与BFS|树与图的遍历:拓扑排序

深度优先搜索DFS DFS每次往最深处搜&#xff0c;搜到叶子节点就返回&#xff0c;然后继续搜&#xff0c;特点&#xff1a;走到头才返回&#xff0c;返回并不是返回最开始&#xff0c;而是每次返回上一层之后&#xff0c;再看这一层能不能往下搜 DFS有回溯和剪枝。返回上一层的过…

维基百科收录企业或品牌词条的规则解析

作为一家知名企业&#xff0c;开展国外市场营销的前提需要做好海外网络口碑营销&#xff0c;解决品牌信任的问题。小马识途营销顾问近来接到很多关于维基百科的咨询&#xff0c;其实做海外营销的企业倒是很有营销意识&#xff0c;主动寻求创建维基百科的很多&#xff0c;但并不…

138. 复制带随机指针的链表

给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的值。新节点的 n…

ASEMI代理ADCMP600BKSZ-REEL7原装ADI车规级ADCMP600BKSZ-REEL7

编辑&#xff1a;ll ASEMI代理ADCMP600BKSZ-REEL7原装ADI车规级ADCMP600BKSZ-REEL7 型号&#xff1a;ADCMP600BKSZ-REEL7 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;SC-70-5 批号&#xff1a;2023 引脚数量&#xff1a;5 工作温度&#xff1a;-40C~125C 安装类型&am…