你能告诉我是否有std::stringstream
类似物shrink_to_fit
吗?
例如,我使用指定类型的流对数据进行序列化和反序列化。在您工作时,所使用的流线柱会不断扩大,从不收缩。当然,你可以不时手动压缩,但这会对性能产生负面影响,因为压缩流的字符串容量会再次变小,并且当向这样的流添加数据时,膨胀将再次发生。
最小的可重现示例:
#include <sstream>
int main()
{
std::stringstream ss;
for (size_t i = 0; i < 1'000'000'000; ++i)
{
ss.put(i);
ss.get();
}
return 0;
}
Windows
在具有本机编译器的环境中运行时VS 2017
,内存消耗只会增加(在调试版本和发布版本中)。
从理论上讲,这种行为是由实现引起的:它
std::stringstream
存储整个丢弃的行,而不管从中读取什么。从 API 来看,无法控制这一点。最简单的做法是创建一个新的 std::stringstream 并将所有未读入的内容都扔进去。
您可以通过首先请求适量的内存来更有效地执行此操作:
我不能说这可以保证预先分配内存,但它似乎有效。
std::stringstream
或者,您可以为 实现自己的环形缓冲区,而不是使用它,std::iostream
但这是另一回事。从流中读取数据
std::stringstream
不会减小流内部缓冲区的大小。它只是向前移动阅读位置指示器。让我们重写您的测试用例,如下所示:结论:
从程序的输出可以看出,随着数据的写入和读取,相应的位置指示符会移入/移出流。但是从流中读取后,缓冲区大小并没有减少。所有读取的字符都保留在内部缓冲区中。
为了防止内部缓冲区无限增长,在写入/读取数据之前,使用函数将写入/读取位置的指示器移动
seekp()
到seekg()
缓冲区的开头。缓冲区大小不受影响,旧内容不会被清除。简单地写入流将覆盖已经在内部缓冲区中的字符。或者使用
str()
.如果取消注释上面示例中的行
//ss.str("");
,输出将如下所示: