evpp效能測試(2): 與Boost.Asio進行吞吐量對比測試
簡介
Boost.Asio是用於網路和低層IO程式設計的跨平臺C++庫,為開發者提供了C++環境下穩定的非同步程式設計模型。也是業內公認的優秀的C++網路庫代表。一般來講,其他的網路庫的效能如果不能與asio做一下全面的對比和評測,就不能令人信服。
本次測試是參考陳碩的部落格文章muduo 與 boost asio 吞吐量對比,該文章的結論是:muduo吞吐量平均比asio高 15% 以上。
測試物件
測試環境
- Linux CentOS 6.2, 2.6.32-220.7.1.el6.x86_64
- Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHz
- gcc version 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)
測試方法
簡單地說,ping pong 協議是客戶端和伺服器都實現 echo 協議。當 TCP 連線建立時,客戶端向伺服器傳送一些資料,伺服器會 echo 回這些資料,然後客戶端再 echo 回伺服器。這些資料就會像乒乓球一樣在客戶端和伺服器之間來回傳送,直到有一方斷開連線為止。這是用來測試吞吐量的常用辦法。
我們做了下面兩項測試:
- 單執行緒測試,測試併發連線數為 1/10/100/1000/10000 時,訊息大小分別為 4096 8192 81920 409600 時的吞吐量
- 多執行緒測試,併發連線數為 100 或 1000,伺服器和客戶端的執行緒數同時設為 2/3/4/6/8,ping pong 訊息的大小為 4096 bytes。測試用的 shell 指令碼可從
測試結果資料
最終測試結論如下:
在吞吐量方面的效能總體來說,evpp比asio整體上明顯更快,吞吐量高出大約20%~50%
單執行緒測試資料
橫軸是併發數。縱軸是吞吐量,越大越好。
圖表中的evpp-1024
表示訊息大小為1024位元組,其他以此類推,例如evpp-4096
表示訊息大小為4096位元組。
多執行緒測試資料
橫軸是執行緒個數。縱軸是吞吐量,越大越好。
分析
我們有些懷疑上述的測試資料中asio的效能太過差,這當不起boost的大名。另外陳碩的部落格muduo 與 boost asio 吞吐量對比中也提到一些想法:猜測其主要原因是測試程式碼只使用了一個 io_service,如果改用“io_service per CPU”的話,效能應該有所提高
21fc1357d59644400e72a164627c1be5327fbe3d
,並用client2/server2
測試用例。 測試的指令碼用 single_thread.sh 和 multiple_thread.sh。
新的一輪測試下來,我們發現asio的效能上來的,與evpp [moduo]等庫相當。
測試結論
單執行緒場景
詳情請見下面圖表,橫軸是併發數。縱軸是吞吐量,越大越好。
多執行緒場景
詳情請見下面圖表,橫軸是執行緒個數。縱軸是吞吐量,越大越好。
進一步分析
在陳碩的測試中,asio的那個程式沒有發揮出應有的效能,絕對與測試程式本身有關,而不是說asio效能差,這從第二次測試結果可以看出來。
在第二次測試中的多執行緒併發數為100的場景下,asio效能比evpp高出 10% 左右,一開始以為是evpp本身的效能在該場景下差一點,但後來仔細分析了胡大師寫的這個測試程式碼 https://github.com/huyuguang/asio_benchmark 發現,這種ping pong測試中,正好能利用asio的Proactor
的優勢,他幾乎沒有記憶體分配,每次只讀固定大小的資料然後傳送出去,然後用通用的BUFFER來進行下一次讀取操作。而evpp是Reactor
模式的網路庫,其讀取資料很可能不是固定的大小,這就涉及到了一些evpp::Buffer
內部的記憶體重分配問題,導致過多的記憶體分配、釋放、拷貝等動作。
因此,我們準備再做一輪測試,具體方法是模擬現實應用場景下訊息長度不可能固定不變的,每個訊息包括兩部分,前面是HEADER,後面是BODY,HEADER中有BODY的長度,然後讓BODY長度從1增長到100k大小,最後看看兩者之間的效能對比資料。
All benchmark reports
最後
報告中的圖表是使用gochart繪製的。
非常感謝您的閱讀。如果您有任何疑問,請隨時在issue跟我們討論。謝謝。