C での scanf() の使用: cin より高速ですか?
C では、入力に cin と cout を使用すると広く信じられています。また、出力は printf や scanf を使用するよりも大幅に遅くなります。これは、scanf() が C 用に最適化されているのに対し、cin と cout は低速な標準 I/O 関数を使用して実装されているという前提から生じています。
ベンチマーク結果
この主張が成り立つかどうかを判断するために、標準入力から数値のリストを読み取り、それらの XOR を計算するプログラムを使用した簡単なベンチマークが実行されました。プログラムは、iostream と scanf の両方のバージョンを使用して実装されました:
iostream バージョン:
#include <iostream> int main() { int parity = 0; int x; while (std::cin >> x) parity ^= x; std::cout << parity << std::endl; return 0; }
scanf バージョン:
#include <stdio.h> int main() { int parity = 0; int x; while (1 == scanf("%d", &x)) parity ^= x; printf("%d\n", parity); return 0; }
3,300 万を超える乱数からなる大規模なデータセットを使用してテストしたところ、scanf バージョンは完成しました
最適化の影響
コンパイラの最適化設定は結果に大きな影響を与えませんでした。これは、速度の違いが主に scanf() と cin/cout の実装における固有の違いによるものであることを示唆しています。
犯人: std::ios::sync_with_stdio
さらなる調査により、iostream I/O 関数が C I/O 関数との同期を維持していることが判明しました。デフォルトでは、この同期には各入力操作の後に出力バッファのフラッシュが含まれるため、パフォーマンスが低下します。
同期の無効化
幸いなことに、この同期は次の呼び出しによって無効にできます。 std::ios::sync_with_stdio(false):
std::ios::sync_with_stdio(false);
同期を無効にすると、iostream バージョンのパフォーマンスが劇的に向上し、わずか 5.5 秒で完了しました。
C iostream が勝利
同期あり無効にすると、この特定のベンチマークでは C iostream が高速なオプションになります。 std::cout の内部同期が、iostream のパフォーマンス低下の主な原因であることが判明しました。
結論
一部の環境では、scanf() を使用した方が高速になる場合があります。場合によっては、std::ios::sync_with_stdio を無効にすると、特に次のような場合に、iostream が多くのシナリオで scanf よりも優れたパフォーマンスを発揮できるようになります。 stdio 関数と iostream 関数の混合使用を避けます。
以上がC の `scanf()` は入力の `cin` よりも本当に高速ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。