Nerde Nolzda

C++ I/O Performance

你可能聽說 iostream (cout/cin) 比 cstdio (printf/scanf) 慢,但實際上關閉同步後,前者比後者快上不少。還有,以 '\n' 取代 endl 也會使速度大幅加快。
You might have heard that iostream (cout/cin) is slower than cstdio (printf/scanf). However, once you disable synchronization, the former is actually quite faster. Replacing endl with '\n' also increases the speed.

std::cin.tie(0);
std::ios_base::sync_with_stdio(0);

詳細解釋 Explanation

cin.tie

一般來說,為了確保使用者在輸入資料時看見 prompt,會在呼叫 cin 前清除 cout 的 buffer。但對於解題來說,這樣反而會降低速度。因此,便可以使用此函式 untie 這兩者的關係。
Normally, to ensure that the user sees the prompt before entering data, the buffer of cout is cleared before calling cin. However, for competitive programming, this makes the program slower. Thus, this function can be used to untie the two.

sync_with_stdio

在預設設定下,為了避免 iostreamcstdio 發生 race condition (Zh),會將 stream 設為同步。若不需要同時使用這二者,也可以將其關閉,以換取執行效率。
With the default settings, to stop race conditions (En) between iostream and cstdio from occurring, the streams are set as synchronized. If you don’t need to use the two in the same program, you can disable it to get better performance.

endl

很多人會把 endl 作為 '\n' 的替代品,但實際上前者會強制清除 buffer,而這種行為是很少需要的。因此,用後者取代也會帶來不小的效能進步。
Many take endl as an alternative to '\n', but the former flushes the buffer, which is seldom needed. Thus, replacing it with the latter also brings a decent boost in performance.

Benchmark

詳細 benchmark 請看:
Link to benchmark

除此之外,也附上極度優化版的比較:
Link to extremely optimized version

以上程式 compile flags 與 UVa C++11 相同。
The code above is compiled with the same flags as UVa C++11.

Related Posts

0 comments

Post a comment

Send an email to comment@nerde.pw.