Fork me on GitHub

C++中优化IO效率

本文首发于我的个人Blog阿西BUG,欢迎大家批评指正

前言

最近在刷LeetCode的时候,发现时间靠前的答案总是会有以下类似代码

1
2
3
4
5
static const auto xxx = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
return nullptr;
}();

看到这个第一反应是懵逼的,仔细分析了一下,是一个lambda表达式,但是表达式的内容就看的晕晕乎乎了。

正文

参考了网友的部分解答,对上述代码的解答基本如下:
这两段代码的都文件都是 iostream

std::ios::sync_with_stdio()

Sets whether the standard C++ streams are synchronized to the standard C streams after each input/output operation.
设置在每次输入/输出操作后标准C ++流是否与标准C流同步

另有std::cin的解释如下

The global objects std::cin and std::wcin control input from a stream buffer of implementation-defined type (derived from std::streambuf), associated with the standard C input stream stdin.

These objects are guaranteed to be constructed before the first constructor of a static object is called and they are guaranteed to outlive the last destructor of a static object, so that it is always possible to read from std::cin in user code.

Unless sync_with_stdio(false) has been issued, it is safe to concurrently access these objects from multiple threads for both formatted and unformatted input.

Once std::cin is constructed, std::cin.tie() returns &std::cout, and likewise, std::wcin.tie() returns &std::wcout. This means that any formatted input operation on std::cin forces a call to std::cout.flush() if any characters are pending for output.

基本可以了解到,C++为了兼容C语言,保证在代码中同时出现std::cout/std::cin和printf/scanf方法时不发生混乱,所以C++使用了一个缓冲区来同步C的标准IO流,通过使用std::ios::sync_with_stdio(false)来解除这种同步,是cout和cin不再经过缓冲区,进而节省了部分时间。
但是要注意:解除了同步之后,不能再使用C的库函数(scanf,getchar,gets,fgets,fscanf之类)

std::cin.tie

Get/set tied stream
The first form (1) returns a pointer to the tied output stream.

The second form (2) ties the object to tiestr and returns a pointer to the stream tied before the call, if any.

The tied stream is an output stream object which is flushed before each i/o operation in this stream object.

C++11
By default, the standard narrow streams cin and cerr are tied to cout, and their wide character counterparts (wcin and wcerr) to wcout. Library implementations may also tie clog and wclog.

这个理解起来又容易一些,因为std :: cin默认是与std :: cout绑定的,所以每次操作的时候(也就是调用”<<”或者”>>”)都要刷新(调用flush),这样增加了IO的负担,通过tie(nullptr)来解除std :: cin和std :: cout之间的绑定,来降低IO的负担使效率提升。

Enjoy it ? Donate for it ! 欣赏此文?求鼓励,求支持!
>