C# MethodTimer.Fody 使用详解

总目录


前言

NET开发过程中,经常会使用Stopwatch 来测量方法的执行所需时间,以便了解代码的执行效率。这里介绍一个开源库:MethodTimer.Fody。它可以辅助我们更为方便快速的完成方法执行效率的测量。


一、MethodTimer.Fody 是什么?

  • 主页:https://github.com/Fody/MethodTimer
  • MethodTimer.Fody 是一个功能强大的库,可以用于测量 .NET 应用程序中的方法的执行时间。允许你在不修改代码的情况下,自动地测量和记录方法的执行时间。
  • 这个工具是基于.NET的 weaving 技术,通过修改IL(Intermediate Language,中间语言)代码来插入计时逻辑,从而在方法调用前后记录时间戳,进而计算出方法的执行时间。
  • 它使用 Fody 插件框架可以无缝集成到项目中,所以向代码中添加性能测量功能变得非常容易。

二、使用 MethodTimer.Fody

1. 安装与配置

1 安装 MethodTimer.Fody 程序包
在这里插入图片描述

2 引用该程序包后,重新生成项目,一般会在项目目录下会生成一个FodyWeavers.xml 文件,内容如下:

<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"><MethodTimer />
</Weavers>
  • 如果目录下生成FodyWeavers.xml文件,则在vs编辑器中显示所有文件,然后将FodyWeavers.xml文件 包括在项目中
  • 如目录下没生成FodyWeavers.xml文件,则自己新建一个FodyWeavers.xml文件,添加上面的代码即可

2. 使用

1. 指定方法计时

  • 给需要计时的方法添加[Time]特性即可
    internal class Program{static void Main(string[] args){new Program().SayHi();Console.WriteLine("测试方法执行结束");Console.ReadKey();}[Time]public void SayHi(){Console.WriteLine("Hi");}}
  • 运行结果
    在这里插入图片描述

2. 类中所有方法计时

  • [Time]特性添加在Class
    [Time]internal class Program{static void Main(string[] args){new Program().SayHi();new Program().SayGoodBye();Console.WriteLine("测试方法执行结束");Console.ReadKey();}public void SayHi(){Console.WriteLine("Hi");}public void SayGoodBye(){Console.WriteLine("GoodBye");}}
  • 运行结果
    在这里插入图片描述

3. 原理分析

  • 当我们给以下代码添加上特性
    [Time]internal class Program{static void Main(string[] args){new Program().SayHi();new Program().SayGoodBye();Console.WriteLine("测试方法执行结束");Console.ReadKey();}public void SayHi(){Console.WriteLine("Hi");}public void SayGoodBye(){Console.WriteLine("GoodBye");}}
  • 在Main 方法的第一行打断点然后F11逐语句调试,会发现会自动生成以下代码
internal class Program
{private static void Main(string[] args){Stopwatch stopwatch = Stopwatch.StartNew();try{new Program().SayHi();new Program().SayGoodBye();Console.WriteLine("测试方法执行结束");Console.ReadKey();}finally{stopwatch.Stop();Trace.WriteLine("Program.Main " + stopwatch.ElapsedMilliseconds + "ms");}}public void SayHi(){Stopwatch stopwatch = Stopwatch.StartNew();try{Console.WriteLine("Hi");}finally{stopwatch.Stop();Trace.WriteLine("Program.SayHi " + stopwatch.ElapsedMilliseconds + "ms");}}public void SayGoodBye(){Stopwatch stopwatch = Stopwatch.StartNew();try{Console.WriteLine("GoodBye");}finally{stopwatch.Stop();Trace.WriteLine("Program.SayGoodBye " + stopwatch.ElapsedMilliseconds + "ms");}}
}

当我们添加上了Time特性会自动的生成 Stopwatch 相关的代码 对 方法进行计时,并且将测量信息通过Trace.WriteLine 输出

二、自定义测量信息的输出

在上面的示例中我们发现,如果只是添加[Time]特性,计时信息只会在编辑器的【输出】窗口中进行打印输出,如果我们想要在控制台,或者在日志中输出该如何操作呢?

那么我们只需要定义一个静态类即可:

    public static class MethodTimeLogger{//按时段输出public static void Log(MethodBase methodBase, TimeSpan elapsed, string message){Console.WriteLine($"方法:{methodBase.Name} 耗时(时段):{elapsed}, 信息:{message}");}//按总毫秒数输出//public static void Log(MethodBase methodBase, long milliseconds, string message)//{//    Console.WriteLine($"方法:{methodBase.Name} 耗时(总毫秒数):{milliseconds}, 信息:{message}");//}}
  • MethodTimeLogger是MethodTimer.Fody 定义好的切入逻辑,不用去改动,只需要改动逻辑 Log 方法内的输出内容即可。

    • 不要改动MethodTimeLogger 这个类的名称
    • 不要改动Log 这个方法的名称
    • 自定义的内容卸载Log方法中即可。
  • 如果改动Log方法名称,会有报错信息
    在这里插入图片描述

1. 使用MethodTimeLogger

具体示例:

    [Time]internal class Program{static void Main(string[] args){new Program().SayHi();new Program().SayGoodBye();Console.WriteLine("测试方法执行结束");Console.ReadKey();}public void SayHi(){Console.WriteLine("Hi");}public void SayGoodBye(){Console.WriteLine("GoodBye");}}public static class MethodTimeLogger{//按时段输出public static void Log(MethodBase methodBase, TimeSpan elapsed, string message){Console.WriteLine($"方法:{methodBase.Name} 耗时(时段):{elapsed}, 信息:{message}");}//按总毫秒数输出//public static void Log(MethodBase methodBase, long milliseconds, string message)//{//    Console.WriteLine($"方法:{methodBase.Name} 耗时(总毫秒数):{milliseconds}, 信息:{message}");//}}}

当我们定义了MethodTimeLogger 这个静态类的时候,会自动生成如下代码

internal class Program
{private static void Main(string[] args){Stopwatch stopwatch = Stopwatch.StartNew();try{new Program().SayHi();new Program().SayGoodBye();Console.WriteLine("测试方法执行结束");Console.ReadKey();}finally{stopwatch.Stop();string message = default(string);MethodTimeLogger.Log(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/, typeof(Program).TypeHandle), stopwatch.Elapsed, message);}}public void SayHi(){Stopwatch stopwatch = Stopwatch.StartNew();try{Console.WriteLine("Hi");}finally{stopwatch.Stop();string message = default(string);MethodTimeLogger.Log(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/, typeof(Program).TypeHandle), stopwatch.Elapsed, message);}}public void SayGoodBye(){Stopwatch stopwatch = Stopwatch.StartNew();try{Console.WriteLine("GoodBye");}finally{stopwatch.Stop();string message = default(string);MethodTimeLogger.Log(MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/, typeof(Program).TypeHandle), stopwatch.Elapsed, message);}}
}

运行结果如下:
在这里插入图片描述

2. 其他

当我们需要传入相关信息的时候,可以使用如下:

    internal class Program{static void Main(string[] args){new Program().SayHi();Console.WriteLine("测试方法执行结束");Console.ReadKey();}[Time("计时测量")]public void SayHi(){Console.WriteLine("Hi");}}public static class MethodTimeLogger{//按时段输出public static void Log(MethodBase methodBase, TimeSpan elapsed, string message){Console.WriteLine($"方法:{methodBase.Name} 耗时(时段):{elapsed}, 信息:{message}");}}

运行结果:
在这里插入图片描述

在这里插入图片描述


结语

希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
MethodTimer.Fody 统计代码执行时间
C#测试开源运行耗时库MethodTimer.Fody

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

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

相关文章

sourceInsight常用设置和功能汇总(不断更新)(RGB、高亮、全路径、鼠标、宏、TODO高亮)

文章目录 必开配置设置背景颜色护眼的RGB值&#xff1f;sourceInsight4.0中如何设置选中某个单词以后自动高亮的功能&#xff1f;sourceinsight中输入设置显示全路径&#xff1f; 常用sourceInsight4.0中文乱码怎么解决&#xff0c;注意事项是什么&#xff1f;如何绑定鼠标中键…

东土科技孵化的“网联汽车高速通信技术”前沿产品亮相2024WICV大会

2024世界智能网联汽车大会&#xff08;WICV&#xff09;于近日在北京召开。本次大会发布了由中国汽车工程学会组织全球200余位专家&#xff0c;联合评审遴选出未来十年对于智能网联汽车发展具有重要影响的十大技术趋势&#xff0c;包括“面向高级别自动驾驶的超级人工智能”“网…

kvm-dmesg:从宿主机窥探虚拟机内核dmesg日志

在虚拟化环境中&#xff0c;实时获取虚拟机内核日志对于系统管理员和开发者来说至关重要。传统的 dmesg 工具可以方便地查看本地系统的内核日志&#xff0c;但在KVM&#xff08;基于内核的虚拟机&#xff09;环境下&#xff0c;获取虚拟机内部的内核日志则复杂得多。为了简化这…

如何在分布式环境中实现高可靠性分布式锁

目录 一、简单了解分布式锁 &#xff08;一&#xff09;分布式锁&#xff1a;应对分布式环境的同步挑战 &#xff08;二&#xff09;分布式锁的实现方式 &#xff08;三&#xff09;分布式锁的使用场景 &#xff08;四&#xff09;分布式锁需满足的特点 二、Redis 实现分…

编程之路,从0开始:联合和枚举

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路。 目录 1、自定义类型&#xff1a;联合体 1.1联合体的声明 1.2联合体变量的定义与赋值 1.3联合体的特点 1.4利用联合体判断大小端 2、自定义类型&#xff1a;枚举…

【从零开始的LeetCode-算法】3301. 高度互不相同的最大塔高和

给你一个数组 maximumHeight &#xff0c;其中 maximumHeight[i] 表示第 i 座塔可以达到的 最大 高度。 你的任务是给每一座塔分别设置一个高度&#xff0c;使得&#xff1a; 第 i 座塔的高度是一个正整数&#xff0c;且不超过 maximumHeight[i] 。所有塔的高度互不相同。 请…

POE接口

一、POE的概念 POE&#xff08;Power over Ethernet&#xff09;是一种以太网供电技术&#xff0c;它允许在现有的以太网电缆中传输电力和数据信号&#xff0c;从而无需额外的电源线。POE技术广泛应用于IP电话、无线接入点、网络摄像头、安全系统和其他需要网络连接和供电的设…

分层架构 IM 系统之架构演进

在电商业务日活几百万的情况下&#xff0c;IM 系统采用分层架构方式&#xff0c;如下图。 分层架构的 IM 系统&#xff0c;整体上包含了【终端层】、【入口层】、【业务逻辑层】、【路由层】、【数据访问层】和【存储层】&#xff0c;我们在上篇文章&#xff08;分层架构 IM 系…

基于Ruoyi的同一token跨系统访问,后端单点登录并且鉴权方案

基于Ruoyi的同一token跨系统访问,后端单点登录并且鉴权方案 需求场景以及先决条件默认方案改造思路改造代码,一共4个类需要变更完整需要修改的代码 需求场景以及先决条件 同一环境下的多个ruoyi项目,各自使用相同的一组用户(我这里用的是LDAP的登录,不影响本文),但是每个权限拥…

基于Lora通讯加STM32空气质量检测WIFI通讯-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着环境污染问题的日益严重&#xff0c;空气质量的监测与管理已经…

How to paint colors to the assets cube through .urdf

1. Find your assets/cube.urdf Something looks like this <?xml version"1.0"?> <robot name"object"><link name"object"><visual><origin xyz"0 0 0"/><geometry><box size"0.05…

刚学php序列化/反序列化遇到的坑(攻防世界:Web_php_unserialize)

刚开始遇到题目的时候&#xff0c;思路还是很明确。 原题入口&#xff1a;攻防世界 (xctf.org.cn) 中的 Web_php_unserialize 两个函数 serialize() //将一个对象转换成一个字符串 unserialize() //将字符串还原成一个对象 首先看到 unserialize() 可以知道基本上能得…

5G 现网信令参数学习(3) - RrcSetup(2)

前一篇&#xff1a;5G 现网信令参数学习(3) - RrcSetup(1) 目录 1. rlf-TimersAndConstants 2. spCellConfigDedicated 2.1 initialDownlinkBWP 2.1.1 pdcch-Config 2.1.1.1 controlResourceSetToAddModList 2.1.1.2 searchSpacesToAddModList 2.1.2 pdsch-Config 2.1…

在windows上打包mediasoup arm64版本的docker镜像

mediasoup版本&#xff1a;3.14.14 mediasoup-demo版本&#xff1a;v3 windows 10 专业版 docker-desktop版本&#xff1a;4.30.0 (149282) docker info: Client:Version: 26.1.1Plugins:buildx: Docker Buildx (Docker Inc.)Version: v0.14.0-desktop.1Path: C:\Prog…

11.19机器学习_逻辑回归

十二 逻辑回归 1.概念 逻辑回归(Logistic Regression)是机器学习中的一种分类模型&#xff0c;逻辑回归是一种分类算法&#xff0c;虽然名字中带有回归&#xff0c;但是它与回归之间有一定的联系。由于算法的简单和高效&#xff0c;在实际中应用非常广泛。 逻辑回归一般用于…

【LLM训练系列01】Qlora如何加载、训练、合并大模型

示例1&#xff1a;Qlora训练Qwen2.5 参考脚本&#xff1a;https://github.com/QwenLM/Qwen/blob/main/recipes/finetune/deepspeed/finetune_qlora_multi_gpu.ipynb 训练命令如下&#xff1a; !torchrun --nproc_per_node 2 --nnodes 1 --node_rank 0 --master_addr localho…

Jmeter数据库压测之达梦数据库的配置方法

目录 1、概述 2、测试环境 3、数据库压测配置 3.1 安装jmeter 3.2 选择语言 3.3 新建测试计划 3.4 配置JDBC连接池 3.5 配置线程组 3.6 配置测试报告 3.7 执行测试 1、概述 Jmeter是Apache组织开发的基于Java的压力测试工具&#xff0c;用于对软件做压力测试。 它最…

[ 应急响应进阶篇-1 ] Windows 创建后门并进行应急处置-5:启动项后门

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

编译报错:protoc did not exit cleanly. Review output for more information.

目录标题 解决“protoc did not exit cleanly”的报错问题检查.proto文件的语法 解决“protoc did not exit cleanly”的报错问题 今天做的项目需要用到grpc&#xff0c;然后需要编写proto然后编译后实现grpc的具体方法&#xff01; 结果编译的时候报了protoc did not exit cl…

Java码农人生开启手册——重载和重写

一、重载 有时在调用现有方法时会出现参数类型不匹配的问题&#xff0c;在Java中&#xff0c;如果多个方法的名字相同&#xff0c;参数列表不同&#xff0c;则称该几种方法被重载了。 注意&#xff1a; 方法名必须相同参数列表必须不同与返回值是否相同无关编译器在编译代码时&…