std::cin
はテキストモードで開かれているため、あらゆる種類のもの (改行など) を常に監視しています。
入力ストリームによる絶え間ない文字スニッフィングを考えると、std::cin
時間がかかることには驚きませんが、少し過剰に思えます。次のように、ストリームをバイパスiostream
して直接使用すると、FILE
おそらく期待どおりの結果が得られます。
#include <cstdlib>
#include <cstdio>
int main(int argc, char *argv[])
{
static unsigned char const codebook[] =
{
0x00, 0x1E, 0x2D, 0x33, 0x4B, 0x55, 0x66, 0x78,
0x87, 0x99, 0xAA, 0xB4, 0xCC, 0xD2, 0xE1, 0xFF
};
for (int c = std::fgetc(stdin); c!=EOF; c=std::fgetc(stdin))
{
std::fputc(codebook[c >> 4], stdout);
std::fputc(codebook[c & 0x0F], stdout);
}
return EXIT_SUCCESS;
}
上記の正確なa
コードをz
、から までの範囲の文字をロードした 10MB のランダム ファイルでテストしましstd::cin
たstd::cout
。FILE
ストリームを直接使用すると、その違いは非常に大きくなりました。この回答のすべてのコードは、最適化をApple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
使用してテストされました。-O3
FILE
ストリームの使用
time ./hamming < bigfile.txt > bigfile.ham
real 0m1.855s
user 0m1.812s
sys 0m0.041s
std::cin
と_std::cout
time ./hamming < bigfile.txt > bigfile.ham
real 0m23.819s
user 0m7.416s
sys 0m16.377s
std::cin
とstd::cout
の使用std::cout.sync_with_stdio(false);
time ./hamming < bigfile.txt > bigfile.ham
real 0m24.867s
user 0m7.705s
sys 0m17.118s
要約すると、ああ。注目すべきは、システムで費やされた時間です。これをstd::istream::get()
およびput()
メソッドで更新する機会があれば更新しますが、正直なところ、奇跡が起こるとは思っていません。ストリームから io xlat をオフにする何らかの魔法 (他の人ではなく私にとって) がない限り、合理的な代替手段になる可能性がありますstd::cin
。丸呑みが実行可能なオプションであるFILE
かどうかはまだ調査していませんが、有望な可能性もあります。std::cin
rdbuf()
編集:使用std::istreambuf_iterator<char>
streambuf イテレータ クラスを使用すると、本質的にすべてのインライン スラット ジャンクをバイパスするため、大幅に改善されますが、それでもFILE
ストリームほど効率的ではありません。
#include <iostream>
#include <cstdlib>
#include <cstdio>
int main(int argc, char *argv[])
{
static unsigned char const codebook[] =
{
0x00, 0x1E, 0x2D, 0x33, 0x4B, 0x55, 0x66, 0x78,
0x87, 0x99, 0xAA, 0xB4, 0xCC, 0xD2, 0xE1, 0xFF
};
std::istreambuf_iterator<char> cin_it(std::cin), cin_eof;
std::for_each(cin_it, cin_eof, [](char c)
{
std::cout.put(static_cast<char>(codebook[static_cast<unsigned char>(c) >> 4]));
std::cout.put(static_cast<char>(codebook[static_cast<unsigned char>(c) & 0x0F]));
});
return EXIT_SUCCESS;
}
結果:
time ./hamming < bigfile.txt > bigfile.ham
real 0m6.062s
user 0m5.795s
sys 0m0.053s
ストリームsystem
の結果と比較できるようになりましたが、残りの iostream テンプレートからのオーバーヘッドが問題のように見えます (ただし、他の試行よりも優れています)。いくらか勝ち、いくらか失う=PFILE
user
iostream
編集:バッファリングされていないシステムIO
完全に公平を期すために、すべてのランタイム バッファリングをバイパスし、システム コールのみに依存してこの狂気を実行します。次のことも注目に値します。
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
int main(int argc, char *argv[])
{
static unsigned char const codebook[] =
{
0x00, 0x1E, 0x2D, 0x33, 0x4B, 0x55, 0x66, 0x78,
0x87, 0x99, 0xAA, 0xB4, 0xCC, 0xD2, 0xE1, 0xFF
};
unsigned char c;
while (read(STDIN_FILENO, &c, 1)> 0)
{
unsigned char duo[2] =
{
codebook[ c >> 4 ],
codebook[ c & 0x0F ]
};
write(STDOUT_FILENO, duo, sizeof(duo));
}
return EXIT_SUCCESS;
}
ご想像のとおり、結果は恐ろしいものでした。
time ./hamming < bigfile.txt > bigfile.ham
real 0m26.509s
user 0m2.370s
sys 0m24.087s