這篇文章主要介紹.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:
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結果,于是新建一個控制臺程序,代碼如下:
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中關于異步性能測試的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。