什么是更快:多个`发送或使用缓冲?

时间:2010-04-14 15:04:48

标签: python c sockets buffer send

我正在使用C / Python中的套接字,我想知道从Python字典向客户端套接字发送标头的最有效方法是什么。

我的想法:

  1. 对每个标头使用send调用。 优点:无需内存分配。 缺点:许多send次呼叫 - 可能容易出错;错误管理应该相当复杂
  2. 使用缓冲区。 优点一次 send来电,错误检查更容易。 缺点:需要缓冲区:-) malloc / realloc应该相当慢并使用(太)大缓冲区来避免realloc调用浪费内存。< / LI>

    给我的任何提示?谢谢: - )

3 个答案:

答案 0 :(得分:3)

由于TCP拥塞控制的工作方式,一次发送数据的效率更高。 TCP维护一个窗口,显示它将允许“在空中”(已发送但尚未确认)的数据量。 TCP测量返回的确认,以确定它可以“在空中”有多少数据而不会导致拥塞(即丢包)。如果没有足够的数据来自应用程序来填充窗口,TCP无法进行准确的测量,因此会保守地缩小窗口。

如果您只有一些小标题,并且您对send的调用快速连续,操作系统通常会为您缓冲数据并将其全部发送到一个数据包中。在这种情况下,TCP拥塞控制实际上不是问题。但是,对send的每次调用都涉及从用户模式到内核模式的上下文切换,这会导致CPU开销。换句话说,在应用程序中缓存更好。

有(至少)一种情况,在没有缓冲的情况下你会更好:当你的缓冲区慢于上下文切换开销时。如果你用Python编写一个复杂的缓冲区,那很可能就是这种情况。用CPython编写的缓冲区将比内核中精细优化的缓冲区慢得多。很可能缓冲会花费你的钱,而不是你买的。

如有疑问,请测量。

但要提醒一句:过早优化是万恶之源。这里效率的差异非常小。如果您还没有确定这是您的应用程序的瓶颈,那么请选择使您的生活更轻松的任何事情。您可以随时更改。

答案 1 :(得分:0)

除非您发送真正的巨大数据量,否则最好使用一个缓冲区。如果使用几何级数来增加缓冲区大小,则分配数将变为摊销常量,并且通常会分配缓冲区的时间。

答案 2 :(得分:0)

send()调用意味着内核的往返(操作系统中直接处理硬件的部分)。它的单位成本约为几百个时钟周期。除非您尝试拨打send()数百万次,否则这是无害的。

通常,缓冲是指在收集“足够数据”的情况下,偶尔调用send()一次。 “足够”并不意味着“整个消息”,而是“足够的字节,以便内核往返的单位成本相形见绌”。根据经验,传统上认为8-kB缓冲区(8192字节)是好的。

无论如何,对于所有与绩效相关的问题,没有什么比实际措施更好。试试吧。大多数时候,没有任何值得担心的实际性能问题。