.net中关于异步性能测试的示例代码

很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语言的异步性能测试(有关异步和同步的问题,请参考客《aio与bio接口性能对比》),于是我今天写了一个c#的测试程序。

首先,建一个 ASP.NET MVC WebAPI项目,在默认的控制器 values里面,增加两个方法:

 // GET api/values?sleepTime=10         [HttpGet]         public async Task ExecuteAIO(int sleepTime)         {                    await Task.Delay(sleepTime);                    return  "Hello world,"+ sleepTime;        }        [HttpGet]                // GET api/values?sleepTime2=10        public string ExecuteBIO(int sleepTime2)        {            System.Threading.Thread.Sleep(sleepTime2);                        return "Hello world," + sleepTime2;        }

然后,建立一个控制台程序,来测试这个web API:

.net中关于异步性能测试的示例代码.net中关于异步性能测试的示例代码

 class Program    {        static void Main(string[] args)        {            Console.WriteLine("按任意键开始测试 WebAPI:http://localhost:62219/api/values?sleepTime={int}");            Console.Write("请输入线程数:");                        int threadNum = 100;                        int.TryParse(Console.ReadLine(), out threadNum);                        while (Test(threadNum)) ;            Console.ReadLine();            Console.ReadLine();        }        private static bool Test(int TaskNumber)        {            Console.Write("请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:");                        string input = Console.ReadLine();                        int SleepTime = 50;                        if (!int.TryParse(input, out SleepTime))                            return false;            HttpClient client = new HttpClient();            client.BaseAddress = new Uri("http://localhost:62219/");                        var result = client.GetStringAsync("api/values?sleepTime=" + input).Result;            Console.WriteLine("Result:{0}", result);                        //int TaskNumber = 1000;            Console.WriteLine("{0}次 BIO(同步)测试(睡眠{1} 毫秒):", TaskNumber, SleepTime);            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();            sw.Start();            Task[] taskArr = new Task[TaskNumber];                        for (int i = 0; i < TaskNumber; i++)            {                Task task = client.GetStringAsync("api/values?sleepTime2=" + SleepTime);                taskArr[i] = task;            }            Task.WaitAll(taskArr);            sw.Stop();                        double useTime1 = sw.Elapsed.TotalSeconds;            Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime1, TaskNumber/useTime1);            sw.Reset();            Console.WriteLine("{0}次 AIO(异步)测试(睡眠{1} 毫秒):", TaskNumber, SleepTime);            sw.Start();                        for (int i = 0; i < TaskNumber; i++)            {                Task task = client.GetStringAsync("api/values?sleepTime=" + SleepTime);                taskArr[i] = task;            }            Task.WaitAll(taskArr);            sw.Stop();                        double useTime2 = sw.Elapsed.TotalSeconds;            Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime2, TaskNumber / useTime2);                        return true;        }    }

View Code

其实主要是下面几行代码:

HttpClient client = new HttpClient();client.BaseAddress = new Uri("http://localhost:62219/");var result = client.GetStringAsync("api/values?sleepTime=" + input).Result;

注意,你可能需要使用Nuget添加下面这个包:

Microsoft.AspNet.WebApi.Client

最后,运行这个测试,结果如下:

按任意键开始测试 WebAPI:http://localhost:62219/api/values?sleepTime={int}请输入线程数:1000请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10Result:"Hello world,10"1000次 BIO(同步)测试(睡眠10 毫秒):耗时(秒):1.2860545,QPS:    777.571000次 AIO(异步)测试(睡眠10 毫秒):耗时(秒):0.4895946,QPS:   2042.51请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100Result:"Hello world,100"1000次 BIO(同步)测试(睡眠100 毫秒):耗时(秒):8.2769307,QPS:    120.821000次 AIO(异步)测试(睡眠100 毫秒):耗时(秒):0.5435111,QPS:   1839.89

本来想尝试测试10000个线程,但报错了。

 

上面的测试结果,QPS并不高,但由于使用的是IISExpress,不同的Web服务器软件性能不相同,所以还得对比下进程内QPS结果,于是新建一个控制台程序,代码如下:

.net中关于异步性能测试的示例代码.net中关于异步性能测试的示例代码

 class Program    {        static void Main(string[] args)        {            Console.WriteLine("按任意键开始测试 ");            Console.Write("请输入线程数:");                        int threadNum = 100;                        int.TryParse(Console.ReadLine(), out threadNum);                        while (Test(threadNum)) ;            Console.ReadLine();            Console.ReadLine();        }        private static bool Test(int TaskNumber)        {            Console.Write("请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:");                        string input = Console.ReadLine();                        int SleepTime = 50;                        if (!int.TryParse(input, out SleepTime))                            return false;                        var result = ExecuteAIO(SleepTime).Result;            Console.WriteLine("Result:{0}", result);                        //int TaskNumber = 1000;            Console.WriteLine("{0}次 BIO(同步)测试(睡眠{1} 毫秒):", TaskNumber, SleepTime);            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();            sw.Start();            Task[] taskArr = new Task[TaskNumber];                        for (int i = 0; i < TaskNumber; i++)            {                Task task = Task.Run(()=> ExecuteBIO(SleepTime));                taskArr[i] = task;            }            Task.WaitAll(taskArr);            sw.Stop();            double useTime1 = sw.Elapsed.TotalSeconds;            Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime1, TaskNumber / useTime1);            sw.Reset();            Console.WriteLine("{0}次 AIO(异步)测试(睡眠{1} 毫秒):", TaskNumber, SleepTime);            sw.Start();            for (int i = 0; i < TaskNumber; i++)            {                Task task = ExecuteAIO(SleepTime);                taskArr[i] = task;            }            Task.WaitAll(taskArr);            sw.Stop();            double useTime2 = sw.Elapsed.TotalSeconds;            Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime2, TaskNumber / useTime2);                        return true;        }        public static async Task ExecuteAIO(int sleepTime)        {            await Task.Delay(sleepTime);            return "Hello world," + sleepTime;        }        public static string ExecuteBIO(int sleepTime2)        {            System.Threading.Thread.Sleep(sleepTime2);                        //不能在非异步方法里面使用 Task.Delay,否则可能死锁                        //Task.Delay(sleepTime2).Wait();            return "Hello world," + sleepTime2;        }    }

View Code

注意,关键代码只有下面两个方法:

 public static async Task ExecuteAIO(int sleepTime)        {            await Task.Delay(sleepTime);                    return "Hello world," + sleepTime;        }        public static string ExecuteBIO(int sleepTime2)        {            System.Threading.Thread.Sleep(sleepTime2);                        //不能在非异步方法里面使用 Task.Delay,否则可能死锁                        //Task.Delay(sleepTime2).Wait();            return "Hello world," + sleepTime2;        }

这两个方法跟WebAPI的测试方法代码是一样的,但是调用代码稍微不同:

同步调用:

 Task[] taskArr = new Task[TaskNumber];            for (int i = 0; i < TaskNumber; i++)            {                Task task = Task.Run(()=> ExecuteBIO(SleepTime));                taskArr[i] = task;            }            Task.WaitAll(taskArr);

异步调用:

 for (int i = 0; i < TaskNumber; i++)            {                Task task = ExecuteAIO(SleepTime);                taskArr[i] = task;            }            Task.WaitAll(taskArr);

可见,这里测试的时候,同步和异步调用,客户端代码都是使用的多线程,主要的区别就是异步方法使用了 async/await 语句。

下面是非Web的进程内异步多线程和同步多线程的结果:

请输入线程数:1000请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10Result:Hello world,101000次 BIO(同步)测试(睡眠10 毫秒):耗时(秒):1.3031966,QPS:    767.341000次 AIO(异步)测试(睡眠10 毫秒):耗时(秒):0.026441,QPS:  37820.05请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100Result:Hello world,1001000次 BIO(同步)测试(睡眠100 毫秒):耗时(秒):9.8502858,QPS:    101.521000次 AIO(异步)测试(睡眠100 毫秒):耗时(秒):0.1149469,QPS:   8699.67请输入线程数:10000请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10Result:Hello world,1010000次 BIO(同步)测试(睡眠10 毫秒):耗时(秒):7.7966125,QPS:   1282.6110000次 AIO(异步)测试(睡眠10 毫秒):耗时(秒):0.083922,QPS: 119158.27请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100Result:Hello world,10010000次 BIO(同步)测试(睡眠100 毫秒):耗时(秒):34.3646036,QPS:    291.0010000次 AIO(异步)测试(睡眠100 毫秒):耗时(秒):0.1721833,QPS:  58077.64

结果表示,.NET程序开启10000个任务(不是10000个原生线程,需要考虑线程池线程),异步方法的QPS超过了10万,而同步方法只有1000多点,性能差距还是很大的。

注:以上测试结果的测试环境是 

Intel i7-4790K CPU,4核8线程,内存 16GB,Win10 企业版

 

以上就是.net中关于异步性能测试的示例代码的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1432605.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月17日 08:27:23
下一篇 2025年12月17日 08:27:40

相关推荐

  • 静态重定位技术的优势与发展前景的研究

    探究静态重定位技术的优势与发展前景 技术的不断进步为我们带来了很多方便和效率,其中之一就是静态重定位技术。静态重定位技术是一种将程序加载到内存中的技术,通过修改程序中的地址,使其能够在不同的内存位置运行。本文将探究静态重定位技术的优势以及发展前景,并提供一些具体的代码示例作为参考。 静态重定位技术有…

    2025年12月24日
    000
  • 掌握网页性能受绘制和布局的影响

    了解重绘和回流对网页性能的影响,需要具体代码示例 简介:网页的性能是用户体验的关键因素之一。在优化网页性能的过程中,了解重绘和回流的概念及其对网页性能的影响非常重要。本文将详细讲解重绘和回流的含义,并举例说明它们对网页性能的影响。同时,提供一些优化的技巧和建议,以减少重绘和回流的次数,从而提升网页性…

    2025年12月24日
    000
  • 通过使用Web标准,提升网页性能与用户体验的方法

    随着互联网的快速发展,越来越多的企业和个人都开始关注网页的性能和用户体验。一方面,良好的网页性能可以提高网站的可访问性和搜索引擎排名,另一方面,优秀的用户体验可以增加用户的黏性和转化率。而借助Web标准来优化网页性能与用户体验,则成为现如今的一种主流方法。 那么,如何利用Web标准来优化网页性能与用…

    2025年12月24日
    000
  • CSS网页布局优化:提高网页加载速度和性能

    CSS 网页布局优化:提高网页加载速度和性能,需要具体代码示例 随着互联网的发展,用户对于网页加载速度和性能的要求越来越高。而对于网页开发者来说,优化网页布局是提高网页加载速度和性能的重要一环。在本文中,我们将分享一些实用的 CSS 优化技巧,并提供具体的代码示例。 选择合适的布局方式合适的布局方式…

    2025年12月24日
    000
  • 如何使用CSS3动画功能提升网页性能和用户体验

    如何使用CSS3动画功能提升网页性能和用户体验 在如今的互联网时代,网页设计已经成为了人们经常接触的一种艺术形式。而其中,动画效果在网页设计中起到了至关重要的作用,可以为用户呈现出更加生动、丰富的内容,提升用户的使用体验。然而,过多或不适当的动画效果也可能会给网页性能和用户体验带来负面影响。本文将介…

    2025年12月24日
    000
  • 提高css性能的方法

    这篇文章主要介绍了css性能优化提高css性能的方法,不规范的css会导致很多性能问题,所以学习掌握css性能优化技巧是非常必要的,对css性能优化知识感兴趣的朋友一起学习吧 不规范的css会导致很多性能问题,这些问题可能在一些小的项目中不够明显,但是在大型项目中就会显现出来。 css匹配原理 在优…

    好文分享 2025年12月24日
    000
  • 阐述什么是CSS3?

    网页制作Webjx文章简介:CSS3不是新事物,更不是只是围绕border-radius属性实现的圆角。它正耐心的坐在那里,已经准备好了首次登场,呷着咖啡,等着浏览器来铺上红地毯。            CSS3不是新事物,更不是只是围绕border-radius属性实现              …

    好文分享 2025年12月23日
    000
  • jimdo怎么插入html5时间轴_jimdo时间轴html5代码与节点样式【实操】

    Jimdo网站需用自定义HTML5代码实现时间轴:一、内联HTML+CSS轻量嵌入;二、外链CSS+语义化HTML便于复用;三、调用timeline-js-lite库支持交互;四、纯CSS方案零依赖高性能。 如果您希望在 Jimdo 网站中呈现可视化的时间发展脉络,但默认编辑器不支持原生时间轴组件,…

    2025年12月23日
    000
  • visual怎么创建html5_VS新建HTML File选HTML5模板快速创建页面【创建】

    可在Visual Studio中通过新建文件选HTML5模板、新建ASP.NET Core Web App项目或手动创建.html文件并输入及html:5代码段三种方式快速生成HTML5网页。 如果您在 Visual Studio 中需要快速创建一个符合 HTML5 标准的网页文件,则可通过新建项目…

    2025年12月23日
    000
  • jimdo怎么插入html5粒子效果_jimdo粒子效果html5库引入与参数调整【攻略】

    可在Jimdo通过自定义HTML区块引入tsparticles库实现动态粒子效果,或用内联SVG替代;需调整颜色、数量等参数适配主题,并修复脚本加载问题。 如果您希望在 Jimdo 网站中添加动态 HTML5 粒子效果(如背景浮动粒子、鼠标交互连线等),但发现 Jimdo 编辑器默认不支持直接嵌入 …

    2025年12月23日
    000
  • vs.net怎么运行html_vs.net运行html步骤【指南】

    首先创建Web项目或配置外部浏览器预览HTML文件。通过新建ASP.NET项目并添加HTML页面后按Ctrl+F5运行,或安装Live Server等插件实现静态文件实时预览,也可在选项中设置Chrome等外部浏览器直接打开HTML文件以查看效果。 如果您在使用 Visual Studio .NET…

    2025年12月23日
    000
  • vs中如何添加html_VS开发工具中添加HTML文件【工具】

    在 Visual Studio 中添加 HTML 文件需根据项目类型选择方法:一、通过解决方案资源管理器→添加新项→选“HTML 页面”模板;二、手动创建.html文件后通过“显示所有文件”→“包括在项目中”;三、用快捷键Shift+Alt+A快速调出模板;四、若无模板,需通过 Visual Stu…

    2025年12月23日
    000
  • HTML如何弹出提示框_JavaScript交互实现方法【指南】

    JavaScript提供五种弹出提示框方法:alert()显示不可编辑警告;confirm()返回布尔值实现确认交互;prompt()获取用户文本输入;自定义DOM元素实现灵活样式;第三方库如SweetAlert2支持美观异步提示。 如果您希望在网页中向用户显示简短信息、确认操作或获取简单输入,Ja…

    2025年12月23日
    000
  • vscode运行html慢怎么办_解vscode运行html慢问题【技巧】

    使用Live Server插件启动本地服务器预览HTML,禁用非必要扩展以释放资源,优化大体积静态文件引入方式,清除浏览器缓存并切换至高性能浏览器,调整VSCode自动保存与文件监听设置,可显著提升加载速度。 如果您在使用VSCode运行HTML文件时发现加载或预览速度较慢,可能是由于插件配置、浏览…

    2025年12月23日
    000
  • vs怎么编写并运行html_vs编写并运行html方法【教程】

    Visual Studio中运行HTML的方法包括:1. 创建ASP.NET项目,添加HTML文件并设为起始页,通过IIS Express运行;2. 使用VS Code安装Live Server扩展实现实时预览;3. 直接保存HTML文件后用浏览器手动打开查看效果。 如果您在使用 Visual St…

    2025年12月23日
    000
  • vs如何写html_vs编写html步骤【教程】

    在Visual Studio中编写HTML需依次创建ASP.NET Core Empty项目、添加index.html文件、编辑保存内容、用浏览器预览,并可安装Live Server扩展实现保存即刷新。 如果您希望在 Visual Studio 中编写 HTML 文件,但不确定如何创建项目、添加文件…

    2025年12月23日
    000
  • visal stdio怎么运行html_visual studio运行html步骤【指南】

    首先安装“ASP.NET和Web开发”工作负载,创建或打开项目后添加HTML文件,编写代码并设为起始页,最后按Ctrl+F5通过IIS Express运行,可在浏览器中预览页面效果。 在 Visual Studio 中运行 HTML 文件并不复杂,只要配置正确,可以快速预览网页效果。以下是详细步骤,…

    2025年12月23日
    000
  • html5如何使用视频_在HTML5中嵌入与控制视频播放【播放】

    可使用HTML5的元素嵌入视频并实现播放控制:通过src、controls等属性基础嵌入;用JavaScript调用play()、pause()等方法控制行为;配合autoplay与muted实现自动播放;采用响应式容器适配多屏;监听error事件并用canPlayType()处理兼容性问题。 如果…

    2025年12月23日
    000
  • 使用Bulma创建固定导航栏、页脚与可滚动内容区域的教程

    本文详细介绍了如何在bulma框架中实现固定顶部导航栏、固定底部页脚,并使中间内容区域可独立滚动。通过利用bulma提供的`is-fixed-top`、`is-fixed-bottom`类以及在`html>`标签上添加相应的`has-navbar-fixed-top`和`has-navbar-…

    2025年12月23日
    000
  • 在 Bulma 中实现固定导航栏、页脚与可滚动主体内容

    本文旨在指导您如何在 Bulma 框架中构建一个具备固定顶部导航栏和底部页脚,同时允许中间主体内容区域自由滚动的页面布局。通过利用 Bulma 提供的 `is-fixed-top` 和 `is-fixed-bottom` 类,并配合 HTML 元素的辅助类,您可以轻松实现这一常见的 UI 需求,避免…

    2025年12月23日 好文分享
    000

发表回复

登录后才能评论
关注微信