我使用C ++ Std库方法std :: ostream :: write()观察到以下行为。
为了缓冲数据我正在使用以下C ++ API
std::ofstream::rdbuf()->pubsetbuf(char* s, streamsize n)
这个工作正常(使用strace实用程序验证),只要我们使用
在文件流上写入数据(datasize)的大小std::ofstream::write (const char* s, datasize n)
小于1023字节(低于此值,写入累积直到缓冲区未满),但是当要写入的数据大小超过1023时,不考虑缓冲区并将数据刷新到文件
e.g。如果我将缓冲区大小设置为10KB并且每次写入大约512字节,则strace将显示多个写入已合并为单个写入
writev(3, [{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 9728}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 512}], 2) = 10240 ( 10 KB )
writev(3, [{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 9728}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 512}], 2) = 10240
...
但是当我每次写入1024个字节(保持缓冲区固定为10 KB)时,现在strace告诉我它没有使用缓冲区,并且每个ofstream :: write调用都被转换为写入系统调用。
writev(3, [{NULL, 0}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024}], 2) = 1024 ( 1KB )
writev(3, [{NULL, 0}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024}], 2) = 1024
...
我缺少任何C ++ API调用或Linux调优参数吗?
答案 0 :(得分:2)
这是libstdc ++的实现细节,在bits / fstream.tcc的第650行附近实现。基本上,如果写入大于2 ^ 10,它将跳过缓冲区。
如果您想了解此决定背后的理由,我建议您发送邮件到libstdc ++开发列表。
答案 1 :(得分:1)
看起来像编写stdlib实现的人做了一个“优化”而没有给予足够的考虑。因此,唯一的解决方法是避免使用C ++ API并使用标准C库。
这不是标准C ++库的GNU / Linux实现中唯一的次优性:在我的机器上,malloc()
比标准void* operator new (size_t size)
快100个循环......