同事轉了一篇探討 WCF 與 ASP.NET Core WebAPI 效能的比較文章: Is WCF faster than ASP.NET Core- Of course not! Or is it? 結論出乎意料。

作者看到一則 Reddit 上關於 WCF/ASP.NET WebAPI 效能討論 (Reddit 可想成國外的 PTT) 就認真了,跑了蠻專業的測試,試了多種組合,WCF 幾乎都輕鬆將 ASP.NET Core WebAPI 甩在身後。進一步分析,JSON Serializer 似乎是速度的關鍵,當物件複雜化,改用 MessagePack 格式序列化的 ASP.NET/ASP.NET Core WebAPI 組終於以小幅差距打敗 WCF。
 
這個結果顛覆我的想像,我原以為 ASP.NET Core 跟 OWIN 一樣採模組化設計,處理環節可自由切換組裝, 相較內建支援各種 Binding 管道邏輯的 WCF,ASP.NET Core 的 Middleware 概念,沒用到的就不載入,理應更輕巧,Overhead 更低才是,沒想到竟然大輸。而由更換 Serializer 變快這點,推測慢的關鍵可能出在以彈性易擴充著稱的 Json.NET 上,但測試裡採用 DataContractJsonSerializer 的 SmallWcfWebJson 依然大勝 SmallAspNetCoreUtf8Json,則狠狠打臉 Json.NET 是頭號戰犯的推論。 (WCF 採用的是比 Json.NET 還慢的 DataContractJsonSerializer [依據 Json.NET 自家評測],而
Utf8Json 又比 Json.NET 更快,SmallWcfWebJson 比 SmallAspNetCoreUtf8Json 快這點足為 Json.NET 的不在場證明)。

最後,我的個人看法是 ASP.NET Core 雖主打 Middleware 可抽換組裝,但作者測試時採用的是 WCF 及 ASP.NET Core 預設值,故測試數據是二者預設的效能表現,而非其極限。依 ASP.NET Core 的設計哲學,允許你拆除座椅、丟棄備胎、拿掉安全氣囊,不計代價減重以提升賽車速度,其可調整空間遠遠勝過 WCF,但在該測試中並未發揮展現。

不用說,文章在社群引發論戰,一堆人跑出來抗議競賽不公,所以作者補了第二篇文章:Revisited- Is WCF faster than ASP.NET Core- Of course not! Or is it? 重申一些觀點並補充幾項測試:

  1. 速度從來不是選擇 WCF 或 WebAPI 的唯一考量
  2. 測試觀測對象是 Latency(延遲),並不等於效能
    作者推測 ASP.NET Core 與 Kestrel 被設計成可以處理大量同時湧入的 Request,單一 Request 延遲較高可能是換取網站整體效能提升的代價。這有點像是「提高 CPU 時脈」、「加大 M1/M2 Cache」與「增加 CPU 核數」間的抉擇,各有其擅長的情境。
  3. 依網友回響,作者改用 Overhead 較低的 HttpWebRequest 重寫 WebAPI 測試,有效提升效能,這回 MessagePack 及 Utf8Json 版 WebAPI 打敗 WCF。
  4. 作者加碼再測了 NetTcpBinding,WCF 提升一倍速度,打敗 MessagePack 版 ASP.NET Core WebAPI。
  5. MsgPack.Cli 表現遠不如 MessagePack
  6. ZeroFormatter 小輸 MessagePack

看完兩篇文章,歸納心得如下:

  • 在預設配置下,WCF 的 HTTP 延遲比 ASP.NET Core Web API 低,抽換改用 MessagePack 或 Utf8Json 序列化才勝出
  • HTTP 延遲不等於效能,有可能單一 Request 延遲較久,但整體網站效能反而更高。
  • ASP.NET Core 可依需求調整優化 Middleware 層,光憑這點,我深信 ASP.NET Core 比 WCF 更容易調出超變態的效能數字。但跟拆掉座椅改用超薄鈑金追求賽車極速數字一樣,為求速度不顧安全、穩定、可靠性,在實務上意義不大。
  • 測試數據差異只在毫秒等級,在實務環境混入資料庫存取、檔案讀寫、複雜商業邏輯運算後,這點差異往往微不足道,除非其他環節都已優化到毫秒等級而且 Request 數量驚人,否則很難有感。
  • 會因為這個評比改用 WCF 嗎?
    不會。API 平台選擇仍維持原判:閒談:.NET Remoting、WCF、WebAPI、Socket,該怎麼選?
  • 會因為這個評比改用 Utf8Json 或其他更快的 JSON 序列化程式庫嗎?
    除非 JSON 序列化是效能瓶頸,否則不會。.JsonNET 我已經用得很順手,先前遇過不少刁鑽需求,其功能完整性與擴充彈性都沒讓我失望過,「速度不是最快的」不足成為換掉它的理由。

最後補上一段小插曲,這個議題引來同事與我的有趣對話:

同事:這讓我有點懷念起WCF... 看起來 WCF 沒那麼不堪, 對吧?
黑大:No Way,我絕不會為這點小確幸回頭。 WCF 的不堪從來不在效能上,而是設定不對或運作不正常時讓你查到痛不欲生啊~ 就像很帥但動不動會打人的前男友,或是超正但三不五時爆發公主病的前女友。
同事:我對 WCF 從來沒深入過,也許是我自己功力不夠,哈。
(稍後)
同事:想想也對,自殘型男友是這樣沒錯:是我不夠了解女友,都是我的錯... blah blah

哈!

A Reddit discussion showed WCF is way faster than ASP.NET Core. After some survey, my conclussion is that ASP.NET Core is flexible enough for extreme peformance-oriented tunning and simpler configuration is the big advantage over WCF.


Comments

# by zk

我觉得主要区别还是在应用场景不同。

# by jinxiu0406

好比是以前的 asp.net web控件,可视化编辑,状态保持,等各种有点。看似很好用。其实很不好用。很不灵活。于是被淘汰。

Post a comment