. Net asynchronous performance testing (including ASP. net mvc WebAPI Asynchronous Method), mvcwebapi

Source: Internet
Author: User

. Net asynchronous performance testing (including ASP. net mvc WebAPI Asynchronous Method), mvcwebapi

I haven't written a blog for a long time. This year, the product company launched a press conference just two days ago, so I thought about whether there is room for performance optimization for our products. net Asynchronization can optimize the performance, but how much can it increase? A friend is testing the asynchronous performance of various languages. (For more information about asynchronous and Synchronous Performance, see AIO and BIO interface performance comparison.) so today I wrote a C # test program.

First, create an ASP. net mvc WebAPI project. In the default controller values, add two methods:

 // 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;        }

Then, create a console program to test the web API:

Class Program {static void Main (string [] args) {Console. WriteLine ("press any key to start testing WebAPI: http://localhost:62219/ Api/values? SleepTime = {int} "); Console. write ("Enter the number of threads:"); int threadNum = 100; int. tryParse (Console. readLine (), out threadNum); while (Test (threadNum); Console. readLine (); Console. readLine ();} private static bool Test (int TaskNumber) {Console. write ("Enter the sleep time (ms) of this API method, enter non-numeric content to exit:"); 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 (synchronous) test (sleep {1} millisecond):", 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 ("elapsed time (seconds): {0}, QPS: {: f2}", useTime1, TaskNumber/useTime1); sw. reset (); Console. writeLine ("{0} AIO (asynchronous) test (sleep {1} millisecond):", 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 ("elapsed time (seconds): {0}, QPS: {: f2}", useTime2, TaskNumber/useTime2); return true ;}}View Code

The following code is used:

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

Note: you may need to use Nuget to add the following package:

Microsoft. AspNet. WebApi. Client

Finally, run the test and the results are as follows:

Press any key to start testing WebAPI: http: // localhost: 62219/api/values? SleepTime = {int} enter the number of threads: 1000 enter the sleep time of this API method (in milliseconds), enter non-numeric content to exit: 10 Result: "Hello world, 10 "1000 BIO (synchronous) tests (10 milliseconds of sleep): Time consumed (seconds): 1.2860545, QPS: 777.571000 AIO (asynchronous) tests (10 milliseconds of sleep ): time consumed (seconds): 0.4895946, QPS: 2042.51 enter the sleep time (milliseconds) of this API method, enter non-numeric content to exit: 100 Result: "Hello world, 100 "1000 BIO (synchronous) tests (100 milliseconds of sleep): Time consumed (seconds): 8.2769307, QPS: 120.821000 AIO (asynchronous) tests (100 milliseconds of sleep ): time consumed (seconds): 0.5435111, QPS: 1839.89

I tried to test 10000 threads but reported an error.

 

The above test results show that the QPS is not high, but because IISExpress is used, the performance of different Web server software is different, so we have to compare the QPS results in the process, so we create a new console program, the Code is as follows:

Class Program {static void Main (string [] args) {Console. writeLine ("start the test by pressing any key"); Console. write ("Enter the number of threads:"); int threadNum = 100; int. tryParse (Console. readLine (), out threadNum); while (Test (threadNum); Console. readLine (); Console. readLine ();} private static bool Test (int TaskNumber) {Console. write ("Enter the sleep time (ms) of this API method, enter non-numeric content to exit:"); 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 (synchronous) test (sleep {1} millisecond):", 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 = Task. run <string> () => ExecuteBIO (SleepTime); taskArr [I] = task;} Task. waitAll (taskArr); sw. stop (); double useTime1 = sw. elapsed. totalSeconds; Console. writeLine ("elapsed time (seconds): {0}, QPS: {: f2}", useTime1, TaskNumber/useTime1); sw. reset (); Console. writeLine ("{0} AIO (asynchronous) test (sleep {1} millisecond):", 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 ("elapsed time (seconds): {0}, QPS: {: 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); // tasks cannot be used in non-asynchronous methods. delay. Otherwise, a deadlock may occur. // Task. delay (sleepTime2 ). wait (); return "Hello world," + sleepTime2 ;}}View Code

Note that the key code has only the following two methods:

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); // tasks cannot be used in non-asynchronous methods. delay. Otherwise, a deadlock may occur. // Task. delay (sleepTime2 ). wait (); return "Hello world," + sleepTime2 ;}

The two methods are the same as the WebAPI test method code, but the call code is slightly different:

Synchronous call:

 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);

Asynchronous call:

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

It can be seen that during the test, both synchronous and asynchronous calls and client code use multiple threads. The main difference is that asynchronous methods use async/await statements.

The following are non-Web asynchronous multithreading and synchronous multithreading results:

Enter the number of threads: 1000. Enter the sleep time (ms) of this API method, enter non-numeric content, and exit: 10 Result: Hello world, 101000 BIO (synchronization) test (sleep for 10 milliseconds): Time consumed (seconds): 1.3031966, QPS: 767.341000 AIO (asynchronous) tests (sleep for 10 milliseconds): Time consumed (seconds): 0.026441, QPS: 37820.05 enter the sleep time (ms) of this API method and enter non-digital content to exit: 100 Result: Hello world, 1001000 BIO (synchronous) tests (100 ms of sleep ): time consumed (seconds): 9.8502858, QPS: 101.521000 AIO (asynchronous) tests (100 milliseconds of sleep): Time consumed (seconds): 0.1149469, QPS: 8699.67 enter the number of threads: 10000 enter the sleep time (ms) of this API method and enter non-digital content to exit: 10 Result: Hello world, 1010000 BIO (synchronous) tests (10 ms of sleep ): time consumed (seconds): 7.7966125, QPS: 1282.6110000 AIO (asynchronous) tests (10 milliseconds of sleep): Time consumed (seconds): 0.083922, QPS: 119158.27 enter the sleep time (ms) of this API method and enter non-digital content to exit: 100 Result: Hello world, 10010000 BIO (synchronous) tests (100 ms of sleep ): time consumed (seconds): 34.3646036, QPS: 291.0010000 AIO (asynchronous) tests (100 milliseconds of sleep): Time consumed (seconds): 0.1721833, QPS: 58077.64

Result Representation ,. NET program to open 10000 tasks (not 10000 native threads, need to consider thread pool threads), Asynchronous Method QPS exceeds 0.1 million, and synchronization method only more than 1000 points, the performance gap is large.

Note: The test environment for the above test results is

Intel i7-4790K CPU, 4-core 8 thread, 16 GB memory, Win10 Enterprise Edition

 

Summary:

Whether it is a common program or a Web program, asynchronous multithreading can greatly improve the system throughput.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.