很久沒有寫部落格了,今年做的產品公司這兩天剛開了發布會,稍微清閒下來,想想我們做的產品還有沒有性能優化空間,於是想到了.Net的異步可以優化性能,但到底能夠提升多大的比例呢?剛好有個朋友正在做各種語言的非同步效能測試(有關非同步和同步的問題,請參考客《AIO與BIO介面效能比較》),於是我今天寫了一個C#的測試程式。
首先,建立一個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中關於非同步效能測試的範例程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

C#和.NET通過不斷的更新和優化,適應了新興技術的需求。 1)C#9.0和.NET5引入了記錄類型和性能優化。 2).NETCore增強了雲原生和容器化支持。 3)ASP.NETCore與現代Web技術集成。 4)ML.NET支持機器學習和人工智能。 5)異步編程和最佳實踐提升了性能。

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

C#.NET面試問題和答案包括基礎知識、核心概念和高級用法。 1)基礎知識:C#是微軟開發的面向對象語言,主要用於.NET框架。 2)核心概念:委託和事件允許動態綁定方法,LINQ提供強大查詢功能。 3)高級用法:異步編程提高響應性,表達式樹用於動態代碼構建。

C#.NET是構建微服務的熱門選擇,因為其生態系統強大且支持豐富。 1)使用ASP.NETCore創建RESTfulAPI,處理訂單創建和查詢。 2)利用gRPC實現微服務間的高效通信,定義和實現訂單服務。 3)通過Docker容器化微服務,簡化部署和管理。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

WebStorm Mac版
好用的JavaScript開發工具

Dreamweaver CS6
視覺化網頁開發工具