我正在使用C / Python中的套接字,我想知道从Python字典向客户端套接字发送标头的最有效方法是什么。
我的想法:
send
调用。 优点:无需内存分配。 缺点:许多send
次呼叫 - 可能容易出错;错误管理应该相当复杂send
来电,错误检查更容易。 缺点:需要缓冲区:-) malloc
/ realloc
应该相当慢并使用(太)大缓冲区来避免realloc
调用浪费内存。< / LI>
醇>
给我的任何提示?谢谢: - )
答案 0 :(得分:3)
由于TCP拥塞控制的工作方式,一次发送数据的效率更高。 TCP维护一个窗口,显示它将允许“在空中”(已发送但尚未确认)的数据量。 TCP测量返回的确认,以确定它可以“在空中”有多少数据而不会导致拥塞(即丢包)。如果没有足够的数据来自应用程序来填充窗口,TCP无法进行准确的测量,因此会保守地缩小窗口。
如果您只有一些小标题,并且您对send
的调用快速连续,操作系统通常会为您缓冲数据并将其全部发送到一个数据包中。在这种情况下,TCP拥塞控制实际上不是问题。但是,对send
的每次调用都涉及从用户模式到内核模式的上下文切换,这会导致CPU开销。换句话说,在应用程序中缓存更好。
有(至少)一种情况,在没有缓冲的情况下你会更好:当你的缓冲区慢于上下文切换开销时。如果你用Python编写一个复杂的缓冲区,那很可能就是这种情况。用CPython编写的缓冲区将比内核中精细优化的缓冲区慢得多。很可能缓冲会花费你的钱,而不是你买的。
如有疑问,请测量。
但要提醒一句:过早优化是万恶之源。这里效率的差异非常小。如果您还没有确定这是您的应用程序的瓶颈,那么请选择使您的生活更轻松的任何事情。您可以随时更改。
答案 1 :(得分:0)
除非您发送真正的巨大数据量,否则最好使用一个缓冲区。如果使用几何级数来增加缓冲区大小,则分配数将变为摊销常量,并且通常会分配缓冲区的时间。
答案 2 :(得分:0)
send()
调用意味着内核的往返(操作系统中直接处理硬件的部分)。它的单位成本约为几百个时钟周期。除非您尝试拨打send()
数百万次,否则这是无害的。
通常,缓冲是指在收集“足够数据”的情况下,偶尔调用send()
一次。 “足够”并不意味着“整个消息”,而是“足够的字节,以便内核往返的单位成本相形见绌”。根据经验,传统上认为8-kB缓冲区(8192字节)是好的。
无论如何,对于所有与绩效相关的问题,没有什么比实际措施更好。试试吧。大多数时候,没有任何值得担心的实际性能问题。