stdin/stdout (STL) ——稳中求胜还是寻求快活?

std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
熟悉吗?熟悉啊!
在调用 ios::sync_with_stdio(false) 后,cout与stdout不再共享同一块缓冲区,它们分别管理自己的缓冲区。简述,函数作用为设置标准 C++ 流是否与标准 C 流在每次输入/输出操作后同步。正是因为这种同步,所以cin、cout 比 scanf、printf 速度要慢,如果我们在使用 cin、cout 输入输出前加一句 ios::sync_with_stdio(false),即取消缓冲区同步,可节省时间,效率与 scanf、printf 相差无几。

还有(by idiot5lie):
1、实践中,这表示同步的 C++ 流为无缓冲,而每次 C++ 流上的 I/O 都立即应用到对应 C 流的缓冲区。这使得能自由地混合 C++ 与 C I/O 。
2、同步的 C++ 流保证为线程安全(从多个线程输出的单独字符可能交错,但无数据竞争)。
3、若关闭同步,则允许 C++ 标准流独立地缓冲其 I/O ,可认为这在某些情况下更快。
4、所有八个标准 C++ 流默认与其相应的 C 流同步。
5、若在标准流上已出现 I/O 后调用此函数,则行为是实现定义的:有的实现无效果,有的实现销毁读取缓冲区。

cin 默认是与 cout 绑定,所以每次 cin 操作的时候都在联系流(即输出流)调用 flush(),这样增加了 IO 负担,通过 cin.tie(0) 来解除 cin 和 cout 之间的绑定,进一步加快执行效率。同时,解除绑定带来的效果,详述如下:

cin 默认绑定了 cout 来同步在控制台输出。“绑定”的效果,每当被“绑定”的对象有出入或输出操作,就会即时刷新(本质,在一定刷新频率下刷新)“绑定”的对象的缓冲区,以达到即时回显的效果。cout 没有默认绑定其他输出,所以 cout.tie() 获取到空指针。

代码验证:

#include <iostream>
using namespace std;

int main() {
    cout << "cin.tie(): " << cin.tie() << endl;
    cout << "cin.tie(nullptr): " << cin.tie(nullptr) << endl; // 返回操作前的联系流
    cout << "cin.tie(): " << cin.tie() << endl;
    cout << endl;
    cout << "cerr.tie(): " << cerr.tie() << endl;
    cout << "cerr.tie(nullptr): " << cerr.tie(nullptr) << endl; // 返回操作前的联系流
    cout << "cin.tie(): " << cin.tie() << endl;
    cout << endl;
    cout << "clog.tie(): " << clog.tie() << endl;
    cout << "cout.tie(): " << cout.tie() << endl;
    return 0;
}
//输出:
cin.tie(): 0x55dea3046140
cin.tie(nullptr): 0x55dea3046140
cin.tie(): 0

cerr.tie(): 0x55dea3046140
cerr.tie(nullptr): 0x55dea3046140
cin.tie(): 0

clog.tie(): 0
cout.tie(): 0

部分来自 idiot5lie idiot5lie的博客_CSDN博客-C++,ubuntu,解决问题汇总领域博主

从上文来看,这简直是太快活啦!scanf和printf这么麻烦,用个啥?
说得好!虽然但是…



(题目给的数据范围为n<=100000)
感谢数据的馈赠!!!!
所以?这玩意到底怎么用啊?
想快活,很急( :zipper_mouth_face: bushi),求解qwq

5 个赞

你的解除同步绑定的代码中,使用了换行符 endl,导致每次输出都会刷新缓存区,造成效率的下降。

因此,可以将 endl 替换为 \n,避免频繁的刷新缓存区,以提高效率。

5 个赞