如何用cstdio库更快输出string类型deque中的字符串?
用cstdio快速输出deque的高效方案
我太懂在线评测里卡IO速度的痛苦了!你之前的慢速度大概率是因为多次调用输出函数触发了太多系统调用——毕竟每次printf/puts都要从用户态切换到内核态,次数多了开销就堆起来了。下面给你几个实测有效的提速方法:
方法一:拼接成大字符串后一次性输出(最推荐)
把deque里所有字符串先合并成一个完整的字符串,然后用fwrite一次性输出。这种方法把N次系统调用压缩成1次,速度提升非常明显:
#include <deque> #include <string> #include <cstdio> int main() { std::deque<std::string> str_deque = {"foo", "bar", "baz"}; // 合并所有字符串(如果需要换行可以在每个字符串后加"\n") std::string full_content; for (const auto& s : str_deque) { full_content += s; // full_content += "\n"; // 可选:每个字符串换行 } // 用fwrite直接输出字节流,无格式解析开销 fwrite(full_content.c_str(), sizeof(char), full_content.size(), stdout); fflush(stdout); // 若程序结束前需要立即输出,可加这句;否则程序退出时会自动刷新 return 0; }
fwrite是比printf更底层的IO函数,不需要解析格式字符串,直接把内存里的字节写到标准输出,效率比逐个printf高很多。
方法二:增大stdout缓冲区(内存紧张时用)
如果deque里的字符串总容量太大,拼接成大字符串会占用太多内存,可以通过setvbuf把stdout的缓冲区调大,让系统攒够数据再一次性写入:
#include <deque> #include <string> #include <cstdio> int main() { // 设置1MB的全缓冲(可根据需求调整大小,比如2*1024*1024=2MB) setvbuf(stdout, nullptr, _IOFBF, 1024 * 1024); std::deque<std::string> str_deque = {"foo", "bar", "baz"}; for (const auto& s : str_deque) { puts(s.c_str()); // 或者fwrite(s.c_str(), 1, s.size(), stdout); } return 0; }
默认的stdout缓冲区很小(通常只有几KB),调大后能大幅减少系统调用次数,速度也会有明显提升。
避坑提醒
- 如果你之前用
printf("%s", s.c_str()),换成puts(s.c_str())会略快一点(因为puts不需要解析格式字符串),但还是远不如上面两种方法。 - 如果字符串里包含
%这类格式字符,用printf会出现输出错误,但fwrite和puts完全不受影响,因为它们是直接输出原始字节。
内容的提问来源于stack exchange,提问作者Tammy Von
相关产品推荐
相关产品推荐

