私は自分自身にLinuxのパイプラインのコマンドを書こうとしていました。 stdinから入力を受け取り、処理してstdoutに書き込む、gnu 'cat'やsedのレプリカと考えてください。std :: cin really slow
私は元々AWKスクリプトを書きましたが、私は次のC++のコードを使用し、より高いパフォーマンスを求めていました:
std::string crtLine;
crtLine.reserve(1000);
while (true)
{
std::getline(std::cin, crtLine);
if (!std::cin) // failbit (EOF immediately found) or badbit (I/O error)
break;
std::cout << crtLine << "\n";
}
これはまさに(ない任意のパラメータなし)猫です。 このプログラムはawkと同じくらい遅く、catほど速くはありません。
1GBのファイルでのテスト:
$time cat 'file' | cat | wc -l
real 0m0.771s
$time cat 'file' | filter-range.sh | wc -l
real 0m44.267s
代わりのgetline(はistream、文字列)の私が(バッファサイズ)が、無改良cin.getlineを試してみました。これは恥ずかしいです、それはバッファリングの問題ですか?私は一行ではなく、一度に100KBを取り出してみました。何か案は?
編集: あなたの意見は理にかなっていますが、犯人は文字列の作成/コピーではなく、改行のスキャンもありません。 (また、バッファのサイズもどちらでもない)。これらの2つのプログラムを見てみましょう:
char buf[200];
while (fgets(buf, 200, stdin))
std::cout << buf;
$time cat 'file' | ./FilterRange > /dev/null
real 0m3.276s
char buf[200];
while (std::cin.getline(buf, 200))
std::cout << buf << "\n";
$time cat 'file' | ./FilterRange > /dev/null
real 0m55.031s
それらのどちらもが、文字列を操作し、それらの両方が改行スキャンを行う、しかし、一方が他方よりも17倍遅いです。彼らはcinの使用によってのみ異なる。 私は、cinがタイミングを悪化させることは間違いないと思います。
に基づくものになると思いますrange.sh'?なぜC++プログラムを直接呼び出さないのですか?また、そのループの典型的なパターンは 'while(std :: getline(std :: cin、crtLine)){std :: cout << crtLine <<" \ n "; } '、しかしあなたの質問には影響しません。 –
パフォーマンスをお探しの場合は、cin/coutではなくCスタイルのI/O関数を試してください; – LihO
最適化でコンパイルしましたか? -O2または-O3?それはおそらく44秒を切ることはないでしょうが、あなたがタイミングを心配するならば、それは間違いなく行われるべきです。 – SaulBack