.net中关于异步性能测试的示例代码
导读:收集整理的这篇文章主要介绍了.net中关于异步性能测试的示例代码,觉得挺不错的,现在分享给大家,也给大家做个参考。很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net...
收集整理的这篇文章主要介绍了.net中关于异步性能测试的示例代码,觉得挺不错的,现在分享给大家,也给大家做个参考。很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语言的异步性能测试(有关异步和同步的问题,请参考客《aiO与BIO接口性能对比》),于是我今天写了一个C#的测试程序。首先,建一个 ASP.NET MVC WebAPI项目,在默认的控制器 values里面,增加两个方法:
// GET api/values?sleepTime=10 [HttpGet] public async Taskstring> 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:
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结果,于是新建一个控制台程序,代码如下:
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.Runstring> (()=> 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 Taskstring> 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 Taskstring> 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.Runstring> (()=> 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中关于异步性能测试的示例代码的详细内容,更多请关注其它相关文章!
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: .net中关于异步性能测试的示例代码
本文地址: https://pptw.com/jishu/592921.html