C# Socket:多次发送是否比一次发送效率低?
C# Socket: is multiple sending less efficient than a single send?
我正在编写一个服务于数千个连接的高吞吐量服务器。假设我有 400 个字节要通过套接字发送。假设我有两种方式:
- 调用 Socket.Send() 40 次,每次发送 10 个字节。
- 调用 Socket.Send() 一次,发送 400 个字节。
这两种方式在速度、CPU负载等方面有很大区别吗?
如果 Socket.NoDelay
留在 false
,那么它很少会产生任何影响 - 大多数时候,你只是在本地缓冲 - 尽管多一点 P/Invoke 比绝对必要的开销(由于通过套接字层进行的大量调用)。请注意,Socket.NoDelay
通常应在您关心的任何地方设置为 true
。
如果 Socket.NoDelay
是 true
,那么 如果一切正常工作 ,那么您 可能 引入额外的使用 40 次发送 10 字节的数据包碎片,使用一次发送 400 字节时可以避免这种情况。然而,在许多情况下,OS/hardware 堆栈中的各种抽象和层意味着许多 10 字节块将 可能 最终共享数据包。不过,在最佳情况下,这仍然比 1 个多得多。
另请注意,这始终是一种权衡:数据包碎片会降低总体吞吐量,但如果其他 390 个字节,则更快地发送第一个字节可以减少感知延迟将花费可衡量的(但可能很少)时间来构建。
在大多数情况下:这不太可能成为瓶颈。如果您可以避免数据包碎片而不导致延迟,那可能是可取的。如果是我,我可能更关心有效的缓冲区管理以最大限度地提高可伸缩性,同时避免因 GC 而导致的暂停;像新的“管道”IO API 这样的工具真的可以帮助解决这个问题,并且 Kestrel 可以用来托管基于“管道”的 TCP 服务器,代码比 少如果您编写自己的套接字侦听器,您将使用它 - 然后它会为您处理所有缓冲区管理。
我正在编写一个服务于数千个连接的高吞吐量服务器。假设我有 400 个字节要通过套接字发送。假设我有两种方式:
- 调用 Socket.Send() 40 次,每次发送 10 个字节。
- 调用 Socket.Send() 一次,发送 400 个字节。
这两种方式在速度、CPU负载等方面有很大区别吗?
如果 Socket.NoDelay
留在 false
,那么它很少会产生任何影响 - 大多数时候,你只是在本地缓冲 - 尽管多一点 P/Invoke 比绝对必要的开销(由于通过套接字层进行的大量调用)。请注意,Socket.NoDelay
通常应在您关心的任何地方设置为 true
。
如果 Socket.NoDelay
是 true
,那么 如果一切正常工作 ,那么您 可能 引入额外的使用 40 次发送 10 字节的数据包碎片,使用一次发送 400 字节时可以避免这种情况。然而,在许多情况下,OS/hardware 堆栈中的各种抽象和层意味着许多 10 字节块将 可能 最终共享数据包。不过,在最佳情况下,这仍然比 1 个多得多。
另请注意,这始终是一种权衡:数据包碎片会降低总体吞吐量,但如果其他 390 个字节,则更快地发送第一个字节可以减少感知延迟将花费可衡量的(但可能很少)时间来构建。
在大多数情况下:这不太可能成为瓶颈。如果您可以避免数据包碎片而不导致延迟,那可能是可取的。如果是我,我可能更关心有效的缓冲区管理以最大限度地提高可伸缩性,同时避免因 GC 而导致的暂停;像新的“管道”IO API 这样的工具真的可以帮助解决这个问题,并且 Kestrel 可以用来托管基于“管道”的 TCP 服务器,代码比 少如果您编写自己的套接字侦听器,您将使用它 - 然后它会为您处理所有缓冲区管理。