什么更快:多个“send”还是使用缓冲?

2024-09-29 00:17:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我在玩C/Python中的套接字,我想知道从Python字典向客户机socket发送头的最有效方法是什么。在

我的想法:

  1. 对每个头使用send调用。优点:不需要内存分配。缺点:许多send调用——可能容易出错;错误管理应该相当复杂
  2. 使用缓冲器。专业人士一个send呼叫,错误检查容易得多。缺点:需要缓冲区:-)malloc/realloc应该相当慢,并且使用(太)大的缓冲区来避免realloc调用会浪费内存。在

有什么建议吗?谢谢:-)


Tags: 方法内存send客户机字典错误浪费socket
3条回答

由于TCP拥塞控制的工作方式,一次发送所有数据更有效。TCP维护一个窗口,显示它允许多少数据“在空中”(已发送但尚未确认)。TCP测量返回的确认信息,以计算在不造成拥塞(即,数据包丢失)的情况下,它可以“在空中”有多少数据。如果应用程序没有足够的数据来填充窗口,TCP就不能进行精确的测量,所以它会保守地缩小窗口。在

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

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

有疑问时,量度。在

不过,需要提醒的是:过早的优化是万恶之源。这里的效率差别很小。如果您还没有确定这是应用程序的一个瓶颈,那么就去做那些让您的生活更轻松的事情。你可以以后再改。在

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

通常,缓冲是指在收集到“足够的数据”时偶尔调用send()“足够”并不意味着“整个消息”,而是类似“足够的字节,这样内核往返的单位成本就小了”。根据经验,8kb的缓冲区(8192字节)通常被认为是好的。在

不管怎么说,对于所有与绩效相关的问题,没有什么能比得上实际的衡量标准。试试看。大多数时候,没有任何实际的性能问题值得担心。在

除非你要发送大量的数据,否则最好使用一个缓冲区。如果使用几何级数来增加缓冲区大小,则分配的数量将成为摊余常数,分配缓冲区的时间通常会随之而来。在

相关问题 更多 >