超狂.超提升ASP.NET Web API效能的8種方法(有沒有100倍呀?)

超狂.超提升ASP.NET Web API效能的8種方法(有沒有100倍呀?)

看到一篇 8 ways to improve ASP.NET Web API performance 覺得整理的不錯,順手簡單整理與寫點心得。

  1. 使用最快的 JSON 序列化套件

ASP.NET Web API 預設採用 JSON.NET。JSON.NET 求穩不求快,如果要求快,透過 ASP.NET Web API 優秀擴充點機制,可隨時更換序列化套件。

之前在 Blog 介紹過 Jil

8 Ways作者則是採用 ServiceStack.Text 套件。

JSON Serialization 速度

圖片來源:theburningmonk.com

  1. 從 DataReader 手動進行 JSON 序列化

從 DataReader 去建立 JSON 字串能避免不必要的物件創建,這樣不必在從 DataReader 取值與寫入物件,再從物件中取值在PC使用 JSON Serializer 來產生 JSON 物件。你可以從 JSON Serialization of a DataReader 一文得到詳細的說明。

基本上就是使用 StringBuider 來建立 JSON,最後在使用 StringContent 來作為 ASP.NET Web API 回應內容,例如:

var response = Request.CreateResponse(HttpStatusCode.OK);
// jsonResult 為 StringBuider 建立的 JSON
response.Content = new StringContent(jsonResult, Encoding.UTF8, "application/json");
return response;

這一點我採保留,我個人是建議採用第6點裡的建議,除非真的非用 ADO.NET 不可。

  1. 使用其他協定格式(可能的話)

JSON 的好處是通用性,但在效能議題上就碰到與 JSON.NET 一樣的問題,它能只說是中規中舉。如果要得到高效能的好處,那麼可能要改用更高效的訊息格式(Message Formatter)。例如:Protocol Buffersmessage pack

  1. 實現 GZip 或 Deflate 壓縮

在 ASP.NET Web API 使用 GZip 或 Deflate,對於減少請求與回應封包大小與整理回應速度,是一種投資小量 CPU 能得不少效能提升的手法。

實作方式可以參考我的 Blog 文件:

  1. 使用快取(Caching)

ASP.NET Web API 的快取和一般的 Web 不同,Web API 走的是更完整的 HTTP 協定,一樣能區分用戶端快取與伺服器端快取。以用戶端快取來看,Web 可能會採用 Cookie、Local Storage、Session Storage 等方法,但 Web API 則是採用 HTTP Header 來控制。

如果你本身並無 Redis 等其他快取設計,我在 ASP.NET Web API 的快取是採用 filipw 設計的套件:Strathweb.CacheOutput

另外還有一套 CacheCow 也有人介紹。

  1. 使用傳統 ADO.NET(如果可能)

如果效能對你非常重點,文章作者建立放棄 ORM 回到 ADO.NET 的世界。

我認為這有點矯枉過正,像 Entity Framework 其實執行到最後底層還是 ADO.NET,被包裝過的 ORM 怎麼樣都不可能比原生 ADO.NET 快,但 ORM 帶來的強型別的效益還是很重要的。這兩者之間我們選擇 Dapper 來做為平衡點。

  1. 在 ASP.NET Web API 採用非同步方法

由於 ASP.NET Web API 是一個 REST/HTTP 服務架構,本身特性非常合適採用非同步來執行。比較新版的 .NET Framework (印象中 4.5 之後)提供大量的 *Async() 尾綴的方法。用戶端也建議使用新改寫的 HttpClient 來請求 Web API 服務。

[HttpGet]  
public async Task GetOperationAsync()  
{   
    await Task.Delay(2000);  
}
  1. 回傳多個結果集和集合組合

減少查詢與回應數量,對於用戶端、資料庫和 ASP.NET Web API 三方都有益處。例如,透過 DataModel 來封裝多個物件:

public class AggregateResult
{
     public long MaxId { get; set; }
     public List<Folder> Folders{ get; set; }
     public List<User>  Users{ get; set; }
}

我在「twMVC#22 | 一個微信專案從0到.000的效能調教之路」還提到其他許多非程式面的內容,各位也可以參考:


1 則留言:

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。