【C++】ios::sync_with_stdio(false) 与 cin.tie(nullptr) 加速 IO
目錄&索引
- 一、前言
- 題目
- 二、ios::sync_with_stdio(false)
- 三、cin.tie(nullptr)
- 四、小結
一、前言
之前寫題遇到大數據量(cin、cout 數據量級達到 1e5、1e6 ),因為考慮 IO 性能報錯 TLE,故選擇 scanf、printf 替代 cin、cout,以解決問題。一直以來沒有深入研究其中原因,只知關鍵詞——同步,雖是本質但差之千里,今究其因,記錄本文。
針對上述場景無法 AC,起因是打 LC 周賽發現 top 選手用的下述代碼:
// 已做相關改進,包括 cin.tie(0) 被替換為 cin.tie(nullptr),刪掉不必要的 cout.tie(0),因不涉及本文主題故不詳細展開 using namespace std; ios::sync_with_stdio(false); cin.tie(nullptr);題目
(以本題最短路,報錯 TLE 為例——附題解傳送)
二、ios::sync_with_stdio(false)
在調用 ios::sync_with_stdio(false) 后,cout 與 stdout 不再共享同一塊緩沖區,它們分別管理自己的緩沖區。簡述,函數作用為設置標準 C++ 流是否與標準 C 流在每次輸入/輸出操作后同步(官方文檔,見下圖)。
正是因為這種同步,所以 cin、cout 比 scanf、printf 速度要慢,如果我們在使用 cin、cout 輸入輸出前加一句 ios::sync_with_stdio(false),即取消緩沖區同步,可節省時間,效率與 scanf、printf 相差無幾。
具體功能,需要注意以下幾點:
1、實踐中,這表示同步的 C++ 流為無緩沖,而每次 C++ 流上的 I/O 都立即應用到對應 C 流的緩沖區。這使得能自由地混合 C++ 與 C I/O 。
2、同步的 C++ 流保證為線程安全(從多個線程輸出的單獨字符可能交錯,但無數據競爭)。
3、若關閉同步,則允許 C++ 標準流獨立地緩沖其 I/O ,可認為這在某些情況下更快。
4、所有八個標準 C++ 流默認與其相應的 C 流同步。
5、若在標準流上已出現 I/O 后調用此函數,則行為是實現定義的:有的實現無效果,有的實現銷毀讀取緩沖區。
三、cin.tie(nullptr)
tie 是一個函數,將兩個 stream 綁定,空指針的話返回當前輸出流指針(官方文檔,見下圖)。
函數介紹(注意返回值):
std::basic_ostream<CharT,Traits>* tie() const; // 返回當前聯系流。若無聯系流,則返回空指針。
std::basic_ostream<CharT,Traits>* tie( std::basic_ostream<CharT,Traits>* str ); // 設置當前聯系流為 str ,返回操作前的聯系流。若無聯系流,則返回空指針。
cin 默認是與 cout 綁定,所以每次 cin 操作的時候都在聯系流(即輸出流)調用 flush(),這樣增加了 IO 負擔,通過 cin.tie(nullptr) 來解除 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(): 0cerr.tie(): 0x55dea3046140 cerr.tie(nullptr): 0x55dea3046140 cin.tie(): 0clog.tie(): 0 cout.tie(): 0四、小結
對文章內容有不解,請隨時留言。
總結
以上是生活随笔為你收集整理的【C++】ios::sync_with_stdio(false) 与 cin.tie(nullptr) 加速 IO的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《炬丰科技-半导体工艺》薄膜晶体管中的光
- 下一篇: oracle exp0006,EXP-0