Итак, я пытался написать команду для конвейера Linux.Думайте об этом как о реплике gnu 'cat' или 'sed', которая принимает входные данные из stdin, выполняет некоторую обработку и пишет в stdout.
Первоначально я написал сценарий 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";
}
Это именно то, что делает cat (без каких-либо параметров).Оказывается, эта программа примерно такая же медленная, как и ее аналог awk, и далеко не такая быстрая, как cat.
Тестирование на файле объемом 1 ГБ:
$time cat 'file' | cat | wc -l
real 0m0.771s
$time cat 'file' | filter-range.sh | wc -l
real 0m44.267s
Вместо getline (istream, строка) Я попытался cin.getline (буфер, размер), но без улучшений.Это смущает, это проблема буферизации?Я также попытался получить 100 КБ за раз вместо одной строки, без помощи!Есть идеи?
РЕДАКТИРОВАТЬ: То, что вы, ребята, говорите, имеет смысл, НО преступник не строит / копирует строки и не сканирует строки.(И не размер буфера).Взгляните на эти две программы:
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 портит время.