ASP.NET Web API 是非常棒的技術。編寫 Web API 十分容易,以致於許多開發者沒有在應用程式結構設計上花時間來獲得良好的執行效能。
在本文中,我將介紹8項提高 ASP.NET Web API 效能的技術。
1) 使用最快的 JSON 序列化工具
JSON 的序列化對整個 ASP.NET Web API 的效能有著關鍵性的影響。 在我的一個專案裡,我從 JSON.NET 序列化工具轉到了 ServiceStack.Text 有一年半了。
我測量過,Web API 的效能提升了20%左右。 我強烈建議你去試試這個序列化工具。這裡有一些最近的流行序列化工具性能的比較數據。
來源: theburningmonk
更新: 似乎It seams that StackOverflow 使用了他們號稱迄今為止最快的 JSON 序列化工具 Jil。 一測試資料可參考他們的GitHub page Jil serializer.
2)從DataReader中手動串列化JSON
我已經在我的專案中使用過這種方法,並獲得了在效能上的福利。
你可以手動地從DataReader創建JSON字串並避免不必要的對象創建,這樣你就不用從DataReader中取值並寫入對象,再從這些對像中取值並使用JSON Serializer產生JSON.
使用StringBuilder產生JSON,並在結尾處傳回StringContent作為在WebAPI中回應的內容。
var response = Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(jsonResult, Encoding.UTF8, "application/json"); return response;
你可以在 Rick Strahl's blog查看更多方法
3)盡可能使用其它協議格式(protocol buffer, message pack)
如果你能給在你的工程格式中使用其訊息, MessagePack 而不是使用JSON這種協定格式。
你將能給獲取到巨大的性能優勢,不僅是因為Protocol Buffers 的序列化是非常快,而且比JSON在返回的結果格式化要更快。
4) 實現壓縮
在你的ASP.NET Web API中使用GZIP 或 Deflate 。
對於減少響應包的大小和響應速度,壓縮是一種簡單而有效的方式。
這是一個非常有必要使用的功能,你可以查看更多關於壓縮的文章在我的部落格 ASP.NET Web API GZip compression ActionFilter with 8 lines of code.
5) 使用Webcaching方法中使用output caching意義深遠.舉例來說,如果大量用戶訪問同一個一天只改變一次的響應(response)內容。
如果你想實現手動緩存,例如把用戶口令緩存到內存,請參考我的博文 Simple way to implement caching in ASP.NET Web API.
『6) 盡可能地使用典型的ADO.NET Web API.
『6) 盡可能地使用典型的ADO.NET編寫的ADO.NET仍然是從資料庫中取值的最快的方式。如果Web API的效能對你來說真的很重要,那麼就不要使用ORMs.
你可以看到最流行的ORM之間的效能比較.
Dapper 和hand-written fetch code 很快,果不其然,所有的ORM都比这三种慢.
带有resultset缓存的LLBLGen 很快,但它要重新遍历一遍resultset并重新再内存中实例化对象。
7)在 Web API 中实现异步方法
使用异步的 Web API 服务大幅增加 Web API 对于Http 请求的处理数量。
实现是简单的,只需使用 async 的关键字和 将你方法的返回值类型改为 Task 即可。
[HttpGet] public async Task OperationAsync() { await Task.Delay(2000); }
8) 返回多个结果集和集合的组合
减少传输的次数不仅多数据库有好处,对于 Web API同样 ,你才有可能使用结果集的功能。
也就是说你可以从DataReader去提取多个结果集 参见以下演示代码:
// read the first resultset var reader = command.ExecuteReader(); // read the data from that resultset while (reader.Read()) { suppliers.Add(PopulateSupplierFromIDataReader( reader )); } // read the next resultset reader.NextResult(); // read the data from that second resultset while (reader.Read()) { products.Add(PopulateProductFromIDataReader( reader )); }
你可以在一个 Web API 的一次响应中返回多个对象,试着将你的返回的多个对象进行组合后返回 如下:
public class AggregateResult { public long MaxId { get; set; } public List<Folder> Folders{ get; set; } public List<User> Users{ get; set; } }
这种方式将减少对你的WEB API的HTTP请求。