2016-05-13 5 views
7

私は、コンソールに新しい行を出力する最も効率的な方法が何か不思議でした。なぜ1つの手法がより効率的であるか説明してください。パフォーマンス面で効率的です。例えば改行を出力する最も効率的な方法

cout << endl; 
cout << "\n"; 
puts(""); 
printf("\n"); 

この質問のための動機は、私は出力を持つ私の自己書き込みループを見つけ、私は出力にループのすべての繰り返しの後に新しい行を必要とするということです。私はこれを行う最も効率的な方法が他に何もないと仮定して何かを見つけようとしています。他に何も問題がないというこの仮定はおそらく間違っている。

+2

'fputc( '\ n'、stdout)'? –

+0

すべての例で改行文字が出力されます(オプションで、オペレーティングシステムによっては改行文字が前に付きます)。キャリッジリターンは '\ r'と表示されます。 – kfx

+1

_ @ Harrison Tran_実際の効果は何ですか?テキストフォーマット出力のためのバインディングの中には、 '' \ r ''を拡張することや、 '' flush() ''を明示的に呼び出すことも考えられます。 –

答えて

1

この質問に対する答えは、実際は「それは依存している」です。孤立して

- あなたが測定しているすべてのバッファリングが発生したものを変更しないで、デバイスを微調整ではない、標準出力デバイスに'\n'文字を書くのパフォーマンスであれば -

のようなオプションを打ち負かすのは難しいだろう

問題はこれがあまり成し遂げられないことです(出力が画面または可視アプリケーションウィンドウであると仮定して)カーソルを画面の下に移動し、前の出力を上に移動します。あなたのプログラムのユーザーにとって面白い、あるいは貴重な経験ではありません。だから、あなたはこれを孤立して実行しません。

しかし、改行を孤立して出力しないと、パフォーマンスに影響するものはありますが(測定します)どれどれ;

  • stdout(またはstd::cout)の出力は、デフォルトでバッファリングされます。出力を表示するには、バッファリングをオフにするか、コードがバッファを定期的にフラッシュするかのオプションがあります。 stderr(またはstd::cerr)は、デフォルトでバッファされているため、使用することもできます。stderrもコンソールに向けられ、出力はstdoutと同じパフォーマンス特性を持ちます。
  • stdoutstd::coutが正式にデフォルトで同期化されている(例えばstd::ios_base::sync_with_stdioを見上げる)stdoutstd::coutそこ
  • あなたのコードを出力する場合より改行文字のセットよりも、(同じことがstderrstd::cerrのために行く)への出力の混合を可能にするためにこれらの他の出力を生成する処理(出力に基づくデータのアクセスまたは読み取り)、出力機能による処理などです。
  • パフォーマンスの指標が異なるため、さまざまな手段があります。それぞれに基づいて効率を改善します。たとえば、CPUサイクル、コンソールに表示される出力の合計時間、メモリ使用量など
  • コンソールは物理的な画面である可能性があります。アプリケーションによって作成されたウィンドウ(X、窓)。パフォーマンスは、上記などなど、ハードウェアの選択、ウィンドウ/ GUIサブシステムの実装、オペレーティングシステム、

によって影響されるだけ選択ですが、多かれ少なかれ考えられるかもしれないかを決定する要因が多数ありますパフォーマンス。

10

putchar('\n')は、最も単純でおそらく最も高速です。 coutprintfの文字列が"\n"の場合、NULLで終わる文字列が使用されますが、これは2バイト(0A 00)を処理するため遅くなります。ところで、キャリッジリターンは\r = 13(0x0D)です。 \nコードは改行コード(LF)です。 Ubuntuの15.10で

+0

キャリッジリターンとラインフィードの違いは何ですか? –

+8

@ HarrisonTran - キャリッジリターンは、印刷位置を現在の行の先頭に移動します。改行は、印刷位置を1行下に移動します。一緒に彼らは新しいラインを作ります。しかし、それはあなたが尋ねた質問とは関係がありません。私はこの答えに言及することに戸惑います。 –

+0

レベルが混ざっています。 CとC++では '\ r'は改行で、' \ n'は改行です。 ASCIIでは、0x0Aは改行で、0x0Dは復帰です。ほとんどのコンパイラは便宜上 '\ r'と' \ n'を内部で0x0Dと0x0Aとしてエンコードしていますが、これは要件ではなく実装の詳細です。 –

3

、G ++ v5.2.1(および古いvxWorksの、およびOSE)

std::cout << std::endl; 

出力バッファに改行文字を置くことを実証することが容易であり、次いでバッファをデバイスにフラッシュします。

しかし

std::cout << "\n"; 

は、出力バッファに改行文字を置くと、デバイスに出力しません。バッファ内の改行文字の出力をデバイスにトリガするには、将来の動作が必要になります。

このような2つのアクションは次のとおりです。のstd :: coutのバッファリングのフラッシュをトリガすることができますいくつかの他のアクションも

std::cout << std::flush; // will output the buffer'd new line char 

std::cout << std::endl; // will output 2 new line chars 

があります。


#include <unistd.h> // for Linux 
void msDelay (int ms) { usleep(ms * 1000); } 

int main(int, char**) 
{ 
    std::cout << "with endl and no delay " << std::endl; 

    std::cout << "with newline and 3 sec delay " << std::flush << "\n"; 
    msDelay(3000); 

    std::cout << std::endl << " 2 newlines"; 
    return(0); 
} 

そして、(申し訳ありませんが、私はここに彼の名前をコピーする方法がわからない)を知っている人のコメントごとに、いくつかの環境のための例外があります。

+1

_ "これはデバイスに出力されません。" _これは残念なことに保証されておらず、実際には '\ r'を追加し、 'flush()'をトリガする実装を持つことができます。 –

4

実際にはOS /コンパイラの実装に依存します。

出力へ最も効率的、少なくとも副作用保証方法'\n'改行文字はstd::ostream::write()を使用することです(そしていくつかのシステムのためstd::ostreamstd::ios_base::binaryモードで開かれた必要):

static const char newline = '\n'; 
std::cout.write(&newline,sizeof(newline)); 
6

あなたはしないでください画面の更新を即時に要求するのか、次のフラッシュまで延期するのかを指定します。したがって:

あなたはiostreamのIOを使用している場合:

cout.put('\n'); 

をあなたはstdioのIOを使用している場合:

std::putchar('\n'); 
2

を私が使用することをお勧め:

std::cout << '\n'; /* Use std::ios_base::sync_with_stdio(false) if applicable */ 

fputc('\n', stdout); 

最適化を有効にして、コンパイラにこの簡単な作業を実行するための最良の方法を決定させます。

関連する問題