34

私は長い間 C++ でコーディングしてきました。私はいつもどちらが実行速度が速いのprintfか、それともcout?

状況: C++ でアプリケーションを設計しており、実行時間の制限などの特定の制約があります。私のアプリケーションは、コンソールに印刷コマンドをロードしています。それで、どちらが好ましいでしょうprintfcout

4

15 に答える 15

32

それぞれに独自のオーバーヘッドがあります。印刷する内容によっては、どちらの方が速い場合もあります。

気になるポイントは以下の2点

printf() は「フォーマット」文字列を解析してそれに基づいて動作する必要があるため、コストがかかります。
cout には、より複雑な継承階層があり、オブジェクトを渡します。

実際には、最も奇妙なケースを除いて、違いは問題になりません。それが本当に重要だと思うなら、測定してください!

編集-
ああ、私はこれをやっているとは思わない.

150,000 の "Hello, World!" を (endl を使用せずに) 印刷
するには、printf() で 90 ミリ秒、cout で 79 ミリ秒かかります。

150,000 個のランダム double を出力するには、約 -
printf() で 3450ms、cout で 3420ms かかります。

(10 回の実行の平均)。

違いは非常に小さいので、これはおそらく何の意味もありません...

于 2009-05-22T07:00:33.530 に答える
23

どちらが実行速度が速いか、本当に気にする必要がありますか? どちらもコンソール/stdout にテキストを出力するためだけに使用されますが、これは通常、超高効率を必要とするタスクではありません。さらに言えば、とにかく速度に大きな違いがあるとは思いません (ただし、オブジェクト指向の小さな複雑さが欠けているため、わずかに速いと予想されるかもしれません)。printfただし、ここで I/O 操作を扱っていることを考えると、わずかな違いでさえ、おそらく I/O オーバーヘッドによって圧倒されます。確かに、ファイルに書き込むための同等の方法を比較した場合、それは当てはまります。

printf
'cout' パイピングは、C++ で標準出力にテキストを出力する標準的な方法です 。

これをすべて言って、同じ問題について議論しているcomp.lang.ccグループのスレッドがあります。ただし、パフォーマンス以外の理由でどちらかを選択する必要があるというのがコンセンサスのようです。

于 2009-05-22T07:03:16.550 に答える
15

C++ の cout が遅い理由は、stdio とのデフォルトの同期です。

この問題を無効にするには、次を実行してみてください。

ios_base::sync_with_stdio(false)

http://www.cplusplus.com/reference/iostream/ios_base/sync_with_stdio/

http://msdn.microsoft.com/es-es/library/7yxhba01.aspx

于 2011-09-28T07:23:05.870 に答える
6

少なくとも Windows では、コンソールへの書き込みが大きなボトルネックになるため、「うるさい」コンソール モード プログラムは、サイレント プログラムよりもはるかに遅くなります。そのため、そのプラットフォームでは、コンソールに対応するために使用されるライブラリ関数のわずかな違いは、おそらく実際には大きな違いにはなりません。

他のプラットフォームでは異なる場合があります。また、他の有用な作業と比較して、実行しているコンソール出力の量にも依存します。

最後に、プラットフォームの C および C++ I/O ライブラリの実装に依存します。

したがって、この質問に対する一般的な答えはありません。

于 2009-05-22T07:08:06.997 に答える
5

パフォーマンスは比較の問題ではありません。それが実際に重要なところは何も考えられません(コンソールプログラムの開発)。ただし、考慮すべき点がいくつかあります。

  • Iostream は、va_args の代わりに演算子チェーンを使用します。これは、間違った数の引数を渡したためにプログラムがクラッシュしないことを意味します。これは、printf で発生する可能性があります。

  • Iostream は、va_args の代わりに演算子のオーバーロードを使用します。これは、int を渡し、文字列を予期していたため、プログラムがクラッシュしないことを意味します。これは、printf で発生する可能性があります。

  • Iostream には、フォーマット文字列のネイティブ サポートがありません (これが #1 と #2 の主な根本原因です)。これは一般的には良いことですが、便利な場合もあります。Boost フォーマット ライブラリは、未定義の動作 (printf の場合のように) ではなく、定義された動作 (例外をスロー) を必要とするユーザーのために、この機能を Iostream にもたらします。これは現在、標準外です。

  • Iostream は、printf に相当するものとは異なり、可変長バッファーを直接処理することができ、ハードコードされたクラフトを処理する必要はありません。

カウトに行きます。

于 2009-05-22T07:08:50.723 に答える
4

私は最近、CopyFileEx を使用してファイルをコピーする Windows 上の C++ コンソール アプリケーションに取り組んでおり、コピーごとに「to」パスと「from」パスをコンソールにエコーし、操作の最後に平均スループットを表示していました。

printf を使用してコンソール アプリケーションを実行して文字列をエコーアウトすると、4mb/秒になりました。printf を std::cout に置き換えると、スループットが 800kb/秒に低下しました。

なぜ std::cout 呼び出しがはるかに高価で、各コピーで同じ文字列をエコーアウトして、呼び出しをより適切に比較できるようになったのか疑問に思っていました。比較を均等にするために複数の実行を行いましたが、4 倍の差は持続しました。

次に、stackoverflowでこの回答を見つけました..

stdout のバッファリングをオンにするとうまくいきました。現在、printf と std::cout のスループットの数値はほぼ同じです。

コンソール出力バッファリングで printf と cout がどのように異なるかについては、これ以上深く掘り下げていませんが、コンソールへの書き込みを開始する前に出力バッファを設定すると、問題が解決しました。

于 2011-06-17T15:49:56.400 に答える
3

別のスタック オーバーフローの質問では、C スタイル形式の I/O と C++ iostream の相対速度が取り上げられました。

ただし、ここで説明したベンチマークは、メモリ バッファーへのフォーマットに関するものであることに注意してください。実際にコンソールまたはファイルへの I/O を実行している場合、I/O に全体の時間がかかるため、相対速度の差ははるかに小さくなると思います。

于 2009-05-22T07:41:52.227 に答える
3

C++ を使用している場合は、cout代わりにprintfC ファミリの関数に属する as を使用する必要があります。coutあなたが恩恵を受けることができるように行われた多くの改善があります。速度に関しては、コンソールの I/O がとにかく遅くなるため、問題ではありません。

于 2009-05-22T07:43:48.417 に答える
2

実際には、printf は cout よりも高速であることが常にわかっています。しかし繰り返しになりますが、cout は型の安全性の点でより多くのことを行います。また、printf は単純な関数ですが、cout は複雑なストリーム階層に基づくオブジェクトであるため、実行時間を比較するのは公平ではありません。

于 2009-05-22T07:08:44.733 に答える
1

これを解決するには:

#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;

int main( int argc, char * argcv[] ) {
    const char * const s1 = "some text";
    const char * const s2 = "some more text";
    int x = 1, y = 2, z = 3;
    const int BIG = 2000;
    time_t now = time(0);
    for ( int i = 0; i < BIG; i++ ) {
        if ( argc == 1 ) {
            cout  << i << s1 << s2 << x << y << z << "\n";
        }
        else {
            printf( "%d%s%s%d%d%d\n", i, s1, s2, x, y, z );
        }
    }
    cout << (argc == 1 ? "cout " : "printf " ) << time(0) - now << endl;
}

coutとprintfで同じタイミングを生成します。

于 2009-05-22T08:20:09.450 に答える
0

内部的には、どちらも同じコードを使用するため、速度の違いは問題になりません。

Windowsのみで実行している場合、非標準のcprintf()は、多くのストリームをバイパスするため、より高速になる可能性があります。

ただし、これは奇妙な要件です。誰もそんなに速く読むことはできません。出力をファイルに書き込んでみたら、ユーザーは自由にファイルを閲覧できますか?

于 2009-05-23T09:21:45.843 に答える
0

パフォーマンス上の理由で調べる必要がある場合は、アプリケーションに根本的な問題があります - 他のロギング機能または UI を使用することを検討してください ;)

于 2009-05-22T07:22:21.777 に答える
-2

事例証拠:
ostream 演算子を使用するロギング クラスを設計したことがありますが、実装は非常に低速でした (大量のデータの場合)。

私はそれをあまり分析しなかったので、ostream を正しく使用していないか、単にディスクに記録されたデータの量が原因である可能性があります。(このクラスはパフォーマンスの問題のために廃棄され、実際には printf / fmtmsg スタイルが好まれました。)

ほとんどの場合、それは問題ではないという他の回答に同意します。実際の表示の更新は通常、正しく実装された文字列ビルドよりもコストがかかるため、出力が本当に問題である場合は、それを回避または遅らせる方法を検討する必要があります。とにかく、ミリ秒以内に何千行もスクロールすることはあまり有益ではありません。

于 2009-05-22T08:46:02.190 に答える
-6

ユーザーは両方よりも遅くしか読めないため、この質問をする必要はありません。

高速な実行が必要な場合は、どちらも使用しないでください。

他の人が述べたように、操作の記録が必要な場合は、何らかのログを使用してください。

于 2009-05-22T07:43:03.953 に答える