微軟宣布改進了.NET Core運行時和基礎類庫的性能。雖然沒有像改進ASP.NET Core的性能那樣大肆宣傳,但這些改進同樣重要。
其中,以下10個方面的變化比較顯著:集合、LINQ、壓縮、加密、數學運算、序列化、文本處理、文件I/O、網絡和并發。至于任何一組性能變化如何影響具體的應用程序則取決于具體的使用模式。下面的討論只列出了一些要點,讓你對這些改進有一個大概的了解。其中有許多變化是基于開源Pull Request請求。這樣,一些對于微軟而言因為總體影響極小而不值得實現的重要修改就可以實現了。而這些修改對于很大一部分開發人員而言相當重要。
集合幾乎在任何應用程序中都有廣泛的應用。許多操作都通過簡化集合或降低復雜度得到了改進。其中有些改進得益于減少開銷,如簡化操作實現更好的內聯,或者減少指令數量。SortedSet的構造函數得到了修復,因為最初該構造函數采用了一種簡單的方式編寫,在處理重復時可擴展性不是很好。SortedSet的Min和 Max不需要遍歷整棵樹。List.Add的速度更快了。不只是System.Collections.Generic得到了改進,其他命名空間如System.Collections.Concurrent也得到了改進。 ConcurrentQueue和ConcurrentBag基本上重寫了。LINQ用戶應用僅從集合的改進就可以感受到性能的提升了。
此外,LINQ本身的性能也是一個改進方面。為了減少內存分配的數量和大小以及簡化算法,.NET Core的許多操作符都重寫了。例如,Enumerable.Concat可以確保串聯多個Enumerable時線性增長,而不是指數增長。ToList和Select操作符經過了簡化,減少了內存分配和委托及接口的使用,同時將字段讀寫最小化,避免了復制。Enumerable.ToArray現在對內部緩沖區的管理也更好了。
與集合和LINQ操作內存不同,壓縮通常是受CPU限制。例如,DeflateStream現在使用了一個原生解壓庫。該原生解壓庫也經過了優化。
在加密方面,SHA256.Create使用了一種原生實現,如Windows上的CNG,或Unix上的OpenSSL。
數學運算操作在操作BigInteger時的性能得到了提升。
二進制序列化是CPU、數據和內存密集型的。.NET Core 2.0增加了BinaryFormatter,并允許O(N)算法在切換到O(N2)算法之前使用更長的時間。現在,較大的序列化輸入可以更快地處理了。
對于文本處理,Regex.IsMatch在內存分配方面更高效了,而且,由于數據緩存方式的變化,垃圾收集也更高效了。WebUtility.UrlDecode不再對輸入做實際上并不需要的解碼了。微軟針對一些內置的Encoding派生類型進行了循環優化。
微軟對字符串操作也做了許多改進。Enum.Parse在內存使用方面更高效了,所以垃圾收集也更高效了。各種ToString方法也經過了改進。String類本身的方法也經過了改進,如IndexOf和StartsWith。考慮到字符串在應用程序中使用比較多,這樣的改進應該會產生巨大的影響。
文件I/O經過了改進。使用異步讀寫的FileStreams現在效率更高了。
底層網絡協議棧經過了改進。異步套接字現在允許此類操作實際上同步完成,從而避免異步完成的開銷。這些類型的變化對于使用套接字原語的上層函數有很大的影響。與上層網絡類如NetworkStream和 SslStream相關的工作也是一個改進的來源。
對并發與并行的修改工作已經開展。許多.NET應用程序使用ThreadPool類。例如,QueueUserWorkItem使用一個同步控制和內存分配更少的隊列取代了全局隊列,大大減少了垃圾收集工作。對于類似SpinLock這樣的同步原語,相關的改進工作一直在進行。SpinLock.TryEnter經過了改進,當無法立即獲得鎖時,它會更快地失敗。對于使用這個類的熱門執行路徑,這項改進帶來了巨大的性能提升。
在這一輪的性能改進工作中,有大約1000個Pull Request被合并進來,而需要完成的工作還有許多。總之,在增加基于性能的API及改進現有庫方面,性能提升有更高的優先級。
BenchmarkDotNet對這些修改做了一些獨立的測試。
查看英文原文:.NET Core Runtime and Base Class Library Performance