温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

.net中关于异步性能测试的示例分析

发布时间:2021-07-27 10:59:14 来源:亿速云 阅读:109 作者:小新 栏目:编程语言

这篇文章主要介绍.net中关于异步性能测试的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

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

 // GET api/values?sleepTime=10          [HttpGet]          public async Task<string> 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方法的睡眠时间(毫秒),输入非数字内容退出:10 Result:"Hello world,10" 1000次 BIO(同步)测试(睡眠10 毫秒): 耗时(秒):1.2860545,QPS:    777.57 1000次 AIO(异步)测试(睡眠10 毫秒): 耗时(秒):0.4895946,QPS:   2042.51 请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100 Result:"Hello world,100" 1000次 BIO(同步)测试(睡眠100 毫秒): 耗时(秒):8.2769307,QPS:    120.82 1000次 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<string>(()=> 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<string> 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<string> 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<string>(()=> 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方法的睡眠时间(毫秒),输入非数字内容退出:10 Result:Hello world,10 1000次 BIO(同步)测试(睡眠10 毫秒): 耗时(秒):1.3031966,QPS:    767.34 1000次 AIO(异步)测试(睡眠10 毫秒): 耗时(秒):0.026441,QPS:  37820.05 请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100 Result:Hello world,100 1000次 BIO(同步)测试(睡眠100 毫秒): 耗时(秒):9.8502858,QPS:    101.52 1000次 AIO(异步)测试(睡眠100 毫秒): 耗时(秒):0.1149469,QPS:   8699.67 请输入线程数:10000 请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10 Result:Hello world,10 10000次 BIO(同步)测试(睡眠10 毫秒): 耗时(秒):7.7966125,QPS:   1282.61 10000次 AIO(异步)测试(睡眠10 毫秒): 耗时(秒):0.083922,QPS: 119158.27 请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100 Result:Hello world,100 10000次 BIO(同步)测试(睡眠100 毫秒): 耗时(秒):34.3646036,QPS:    291.00 10000次 AIO(异步)测试(睡眠100 毫秒): 耗时(秒):0.1721833,QPS:  58077.64

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

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

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

以上是“.net中关于异步性能测试的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI