我正在撰寫一個服務于數千個連接的高吞吐量服務器。假設我有 400 個位元組要通過套接字發送。假設我有兩種方式:
- 呼叫 Socket.Send() 40 次,每次發送 10 個位元組。
- 呼叫 Socket.Send() 一次,發送 400 個位元組。
這兩種方式在速度、CPU 負載等方面有很大不同嗎?
uj5u.com熱心網友回復:
如果Socket.NoDelay留在false,那么它很少會產生任何區別 - 大多數時候,你只是要在本地緩沖 - 盡管 P/Invoke 開銷比絕對必要的要多一些(由于通過套接字進行了大量呼叫層)。請注意,Socket.NoDelay通常應true在您關心的任何地方設定為。
如果Socket.NoDelay是true,那么如果一切都最大限度地作業,那么您可能會通過使用 10 位元組的 40 次發送來引入額外的資料包碎片,這在使用 400 位元組的一次發送時可以避免。然而,在許多情況下,作業系統/硬體堆疊中的各種抽象和層意味著很多 10 位元組的塊最終可能會共享資料包。不過,在最佳情況下,這仍然比 1 個資料包多得多。
另請注意,這始終是一種權衡:資料包碎片會降低整體吞吐量,但如果其他 390 位元組將花費可測量(但可能很小)的時間,則更快地發送第一個位元組可以減少感知延遲構造。
在大多數情況下:這不太可能成為瓶頸。如果您可以在不引起延遲的情況下避免資料包碎片,那可能是可取的。如果是我,我可能會更關心有效的緩沖區管理,以最大限度地提高可擴展性,同時避免 GC 導致的暫停;像新的“管道”IO API 這樣的工具真的可以幫助解決這個問題,并且 Kestrel 可以用來托管基于“管道”的 TCP 服務器,代碼比撰寫自己的套接字偵聽器時少得多——而且它然后為您處理所有緩沖區管理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/333371.html
上一篇:如何在精益中使用套接字?
