【发布时间】:2012-12-07 08:56:14
【问题描述】:
这个问题可能看起来很简单,但我认为它并不是那么微不足道。或者也许我想多了,但我还是想知道。
假设我们必须从 TCP 套接字读取数据,直到遇到一些特殊字符。数据必须保存在某个地方。我们不知道数据的大小,所以我们不知道我们的缓冲区有多大。在这种情况下有哪些可能的选择?
随着更多数据到达使用
realloc扩展缓冲区。这种方法提出了一些问题。使用 realloc 对性能有何影响?它可能会移动内存,所以如果缓冲区中有很多数据(并且可能有很多数据),我们将花费大量时间移动字节。我们应该将缓冲区大小扩展多少?我们每次都加倍吗?如果是,那么所有浪费的空间呢?如果我们稍后以较小的大小调用 realloc,它会截断未使用的字节吗?以恒定大小的块分配新缓冲区并将它们链接在一起。 这与 C++ 标准库中的双端队列容器非常相似,允许快速附加新数据。这也有一些问题,比如我们应该做多大的块以及如何处理未使用的空间,但至少它具有良好的性能。
您对此有何看法?这两种方法哪个更好?也许还有其他我没有考虑过的方法?
附:
就个人而言,我更倾向于第二种解决方案,因为我认为如果我们“回收”块而不是每次需要块时都进行动态分配,它可以做得非常快。我能看到的唯一问题是它会损害局部性,但我认为这对我的目的(处理类似 HTTP 的请求)来说并不是非常重要。
谢谢
【问题讨论】:
-
最简单的方法是在标头中包含请求大小。这可能会也可能不会,具体取决于您使用的协议。
-
很遗憾,这是不可能的
-
我个人使用 std::vector 并推回数据,直到我得到所有数据或在你的情况下遇到一些特殊字符。这对我来说是最简单的,到目前为止对我很有帮助。