差距50倍!为什么Web API第一次执行这么慢?

前言

新建一个ASP.NET Core Web API项目,使用命令行方式启动,连续发送多次请求。

从下图的时间线可以发现,第一次执行(116ms)比后面的(2ms)慢了很多:

在这100多ms中,Web API到底做了些什么?!

示例代码

为了更好定位Web API执行情况,示例Controller代码如下:

[HttpGet]
public string Get()
{Thread.Sleep(10);var now = DateTime.Now;while ((DateTime.Now - now).TotalMilliseconds < 10){}var result = HttpContext.TraceIdentifier;Thread.Sleep(10);return result;
}
  • Thread.Sleep用于将框架代码和业务执行代码执行时间分开

  • while循环用于延长业务执行时间,方便找到业务代码

PerfView

PerfView是一款免费的性能分析工具,可帮助排查CPU和内存相关的性能问题。

从https://github.com/Microsoft/perfview/releases下载最新版本PerfView并启动。

配置

点击主界面上的“Collect data machine wide”链接,打开收集数据窗口:

为了记录所有操作,需要设置“CPU Sample Interval”为较小值(0.125)。

收集

  • 使用命令行方式启动Web API

  • 点击收集数据窗口的“Start Collection”按钮

  • 执行Web API请求

  • 再点击“Stop Collection”按钮。

收集完成后,会生成.etl.zip文件:

双击“CPU Stacks”,会打开“Select Process Window”(选择进程窗口),因为PerfView实际收集了所有进程的性能数据。

选择Web API对应的进程,点击“OK”按钮。

火焰图

在打开的窗口中选择“Flame Graph”(火焰图)选项卡,上方的“GroupPats”选择“[group class entries] {%!}.%(=>class $1;{%!}::=>class $1”,可以看到如下效果:

火焰图是用来展示CPU的调用栈的图形:

  • y轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。

  • x轴表示每个函数相对执行的时间长短。

speedscope

由于调用的函数较多,火焰图并不能很清晰地反映。

这时,我们可以使用speedscope,一个交互式火焰图可视化工具,帮助我们分析。

选择菜单"File"->"Save View As",文件类型选择“speed scope”。

打开网站https://www.speedscope.app/,将刚才保存的文件导入,效果如下图:

顶部是线程列表,下面是所选线程对应的火焰图,可以看到它的堆栈顺序与PerfView相反,是从上到下的。

很容易定位到Web API执行的线程,因为可以看到Thread.Sleep留出的2段空白。

分析

图中相同的颜色块表示同一函数,我们只需要找到和业务代码同一行颜色不同的位置,就表示处于不同方法调用中。

先看业务代码执行前,从上往下看,很快就定位到一个运行时间较长的位置:

执行的是Http1Connection.TryParseRequest方法,耗时11.85ms,可见重用连接是非常有必要的

下面是找到的部分耗时比较大的方法:

  • 执行前

    • Microsoft.AspNetCore.Routing.Matching.DfaMatcherFactory.CreateMatcher - 22.73ms

    • Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker - 30.15ms

  • 执行后

    • Microsoft.AspNetCore.Mvc.Formatters.TextOutputFormatter.WriteAsync - 5.79ms

结论

后面请求快的原因也可以解释了,比如重用Http连接,方法内部缓存了结果(DfaMatcherFactory调用了DataSourceDependentCache),这也为提高我们自己程序的性能指明了思路。

PerfView + speedscope确实能够帮助我们分析性能,理解代码执行情况。你还不赶快安排上!

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

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

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

相关文章

Exchange服务器系列课程之四--管理Exchange收件人

前面已经讨论了Exchange的安装&#xff0c;今天我们来讨论一下Exchange服务器的用户管理。管理Exchange的工具在第二篇文章已经讨论过了&#xff0c;这里不再阐述。Exchange中的收件人对象有三种&#xff1a;用户&#xff0c;组&#xff0c;联系人。我们可以为收件人对象启用邮…

动力强劲的星型发动机,为何不用在汽车上呢?

全世界只有3.14 % 的人关注了青少年数学之旅星型发动机嘚瑟的模样&#xff0c;一定让人过目不忘——对&#xff0c;虽然它看起来妖娆&#xff0c;但动力却十分强劲。那它为什么没在汽车上普及呢&#xff1f;我们一起来看看&#xff01;什么是星型发动机星型发动机&#xff0c;顾…

超详细图解!【MySQL进阶篇】存储过程,视图,索引,函数,触发器

超详细图解&#xff01;【MySQL进阶篇】存储过程,视图,索引,函数,触发器1.1 下载Linux 安装包1.2 安装MySQL1.3 启动 MySQL 服务1.4 登录MySQL2\. 索引2.1 索引概述2.2 索引优势劣势2.3 索引结构2.3.1 BTREE 结构2.3.3 BTREE 结构2.3.3 MySQL中的BTree2.4 索引分类2.5 索引语法…

Xcode中release和debug模式

本人对Xcode中的release模式和debug模式很是疑惑,于是今天对其进行的调研,写下笔记以备查阅Debug是调试版本,包含调试信息,并且不做任何优化,便于程序猿进行调试.Release 是发布版本,它往往是进行各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好的使用.在上传…

porting linux

编译器&#xff1a;arm-linux- 3.4.1 出现以下错误 cc1: error: invalid option short-load-bytesmake: *** [entry.o] 错误 1 如果改用2.95.3则不会出现该问题。 原因是高版本的编译器不支持-mshort-load-bytes选项&#xff0c;改为-malignment-traps即可。 makefile中一些易忘…

.Net Core with 微服务 - 分布式事务 - 2PC、3PC

最近比较忙&#xff0c;好久没更新了。这次我们来聊一聊分布式事务。在微服务体系下&#xff0c;我们的应用被分割成多个服务&#xff0c;每个服务都配置一个数据库。如果我们的服务划分的不够完美&#xff0c;那么为了完成业务会出现非常多的跨库事务。即使按照 DDD 的原则来切…

写给还在大学的兄弟姐妹

看到软件专业毕业生之一个月攻略 这篇文章之后&#xff0c;忽然想起了自己两个多月前找工作时的写的一篇文章&#xff0c;便拿出来与大家分享。 这仅是个人的一些看法&#xff0c;不正确之处还请各位指出&#xff0c;有砖尽管拍。 基础很重要 许多企业招聘&#xff0c;要求大学…

2019优质公众号大盘点,果断收藏了慢慢看吧 ~

全世界只有3.14 % 的人关注了青少年数学之旅又到年底了啦&#xff0c;也到了一年一度的年底盘点时间。那么2019年&#xff0c;又有哪些优质公众号崭露头角呢&#xff1f;本期将为您盘点几个优质公众号&#xff0c;总有一个刷屏过你的朋友圈&#xff01;长按二维码&#xff0c;选…

让未备案的网站先飙起来

让未备案的网站先飙起来作者&#xff1a;田逸&#xff08;sery163.com&#xff09;国人在技术方面的创新能力不怎么样&#xff0c;但是在设置障碍&#xff0c;折腾自己人的方面的创造性却登峰造极&#xff0c;比如网站备案。要备案也没什么问题&#xff0c;毕竟大家都是老老实实…

TDengine和DolphinDB哪个更好,哈哈哈哈,闲来无聊分析了一下。

#拥抱开源—涛思数据TDengine有奖征稿# TDengine是专为时序数据设计的&#xff0c;针对的是物联网、工业互联网、IT运维场景。这些场景是不需要特殊的查询函数的&#xff0c;更关心的是写入速度、查询速度。而且这些场景下&#xff0c;也需要一些其他数据库不具备的功能&#…

技术总监谈好的程序员如何写代码

要判断一个程序员是不是好的程序员&#xff0c;主要看他写的代码&#xff0c;因为程序员最重要的事是写代码。 即便不去理解代码的意图&#xff0c;只要看一眼&#xff0c;好的程序员写的代码与差的程序员写的代码基本上就可以看出来。好的程序员写的代码&#xff0c;整洁而规范…

记一次 .NET 某WMS仓储打单系统 内存暴涨分析

一&#xff1a;背景 1. 讲故事七月中旬有一位朋友加wx求助&#xff0c;他的程序在生产上跑着跑着内存就飙起来了&#xff0c;貌似没有回头的趋势&#xff0c;询问如何解决&#xff0c;截图如下&#xff1a;和这位朋友聊下来&#xff0c;感觉像是自己在小县城当了个小老板&#…

C语言面试题之华为篇2(答案全)

C语言面试题之华为篇(答案全) &#xff08;1&#xff09;什么是预编译&#xff0c;何时需要预编译&#xff1a; 答案&#xff1a; &#xff11;、总是使用不经常改动的大型代码体。 &#xff12;、程序由多个模块组成&#xff0c;所有模块都使用一组标准的包含文件和相同的编…

一分钟读懂一个数学时代,看完不跪算我输!

▲ 点击查看上帝说&#xff0c;要有光&#xff0c;于是便有了光。而香农说&#xff0c;要有熵&#xff0c;于是信息化时代正式拉开帷幕。克劳德艾尔伍德香农&#xff08;Claude Elwood Shannon&#xff09;被尊称为“信息论之父”。不管你是否知道他&#xff0c;是如何看待他…

秋招面试我去了拼多多,直接被问JVMGC底层原理和算法,我吊打面试官

JVM 常用参数设置积累 # 堆的初始值&#xff0c;默认物理内存的1/64 -Xms: # 堆的最大值&#xff0c;默认物理内存的1/4 -Xmx: # 年轻代大小「在整个堆内存大小确定的情况下&#xff0c;增大年轻代将会减小年老代&#xff0c;反之亦然。此值关系到JVM垃圾回收&#xff0c;对系…

php中使用exec,system等函数调用系统命令

2019独角兽企业重金招聘Python工程师标准>>> 注意:要想使用这二个函数php.ini中的安全模式必须关闭&#xff0c;要不然为了安全起见php是不让调用系统命令的。  先看一下php手册对这二个函数的解释:  exec --- 执行外部程式  语法 : string exec ( string com…

了解jQuery技巧来提高你的代码

jQuery之所以如此流行并被从大公司到个人博客的几乎每个人都广泛使用&#xff0c;是因为它上手和使用相当简单&#xff0c;而且为我们提供了一些人都不知道的相当棒的特性。我认为jQuery的大多数用户更趋向于使用jQuery插件来解决面临的难题&#xff0c;这通常是明智的选择。但…

Vista Dynamips模拟器安装

原因由于npf文件&#xff0c;缺少这个文件就不能获取网卡参数:解决1&#xff1a;安装Ethereal&#xff0c;在安装过程中勾选“Start WinPcap service "NPF" at startup”这一项.然后就可以获取网卡参数&#xff01;有可能不行&#xff0c;没关系.解决2&#xff1a;输…

如何主动清空.NET数据库连接池?

一般我们的项目中会使用1到2个数据库连接配置&#xff0c;同程艺龙的数据库连接配置被收拢到统一的配置中心&#xff0c;由DBA统一维护&#xff0c;业务方通过某个配置字符串拿到的是开箱即用的Connection对象。DBA能在对业务方无侵入的情况下&#xff0c;给业务方切换备份数据…

Java面试会问的——数组、声明、初始化、冒泡、多维数组、稀疏数组

数组 数组时相同类型数据的有序集合数组描述的是相同类型的若干个数据&#xff0c;按照一定的先后次序排列组合而成其中&#xff0c;每一个数据称作一个数组元素&#xff0c;每一个数组元素可以通过一个下标来访问它们。 数组声明创建 首先必须声明数组变量&#xff0c;才能在…