C++ 真的很慢

C++ 真的很慢,c++,pipeline,cout,cin,C++,Pipeline,Cout,Cin,所以我试着为自己编写一个linux管道的命令。把它想象成gnu“cat”或“sed”的复制品,它从标准输入获取输入,进行一些处理并写入标准输出 我最初写了一个AWK脚本,但是想要更多的性能,所以我使用了下面的C++代码: std::string crtLine; crtLine.reserve(1000); while (true) { std::getline(std::cin, crtLine); if (!std::cin) // failbit (EOF immediat

所以我试着为自己编写一个linux管道的命令。把它想象成gnu“cat”或“sed”的复制品,它从标准输入获取输入,进行一些处理并写入标准输出

<>我最初写了一个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";
}
我尝试了cin.getline(buffer,size)而不是getline(istream,string),但没有改进。这很尴尬,是缓冲问题吗?我还尝试一次获取100KB,而不是一行,没有帮助!有什么想法吗

编辑: 你们说的有道理,但罪魁祸首不是字符串生成/复制,也不是扫描换行符。(缓冲区的大小也是如此)。请看以下两个程序:

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
charbuf[200];
而(fgets(buf、200、stdin))
std::cout/dev/null
实际0m3.276s
char-buf[200];
而(标准::cin.getline(buf,200))
标准::cout
这正是cat(无任何参数)所做的

不是真的。这与/bin/cat的效果完全相同,但使用的方法不同

/bin/cat
看起来更像这样:

while( (readSize = read(inFd, buffer, sizeof buffer)) > 0)
  write(outFd, buffer, readSize);
请注意,
/bin/cat
不对其输入进行处理。它不会从中构建
std::string
,也不会扫描
\n
,它只是一个接一个地执行系统调用

另一方面,您的程序构建
字符串
s,复制它们,扫描
\n

这个小而完整的程序运行速度比/bin/cat慢2-3个数量级:

#include <string>
#include <iostream>

int main (int ac, char **av) {
  std::string crtLine;
  crtLine.reserve(1000);
  while(std::getline(std::cin, crtLine)) {
    std::cout << crtLine << "\n";
  }
}
#include <string>
#include <iostream>
#include <vector>

int main (int ac, char **av) {
  std::vector<char> v(4096);
  do {
    std::cin.read(&v[0], v.size());
    std::cout.write(&v[0], std::cin.gcount());
  } while(std::cin);
}
#包括
#包括
内部主(内部ac,字符**av){
std::字符串crtLine;
储备量(1000);
while(std::getline(std::cin,crtLine)){
std::cout/dev/null

编辑 该程序的性能在/bin/cat的50%以内:

#include <string>
#include <iostream>

int main (int ac, char **av) {
  std::string crtLine;
  crtLine.reserve(1000);
  while(std::getline(std::cin, crtLine)) {
    std::cout << crtLine << "\n";
  }
}
#include <string>
#include <iostream>
#include <vector>

int main (int ac, char **av) {
  std::vector<char> v(4096);
  do {
    std::cin.read(&v[0], v.size());
    std::cout.write(&v[0], std::cin.gcount());
  } while(std::cin);
}
#包括
#包括
#包括
内部主(内部ac,字符**av){
std::向量v(4096);
做{
标准::cin.read(&v[0],v.size());
std::cout.write(&v[0],std::cin.gcount());
}while(std::cin);
}

简言之,如果您的需求是逐行分析输入,那么您将不得不为使用格式化输入付出一些代价。另一方面,如果您需要执行逐字节分析,那么您可以使用非格式化输入并加快速度。

要使sta获得良好性能,您首先要做的事情是标准I/O流对象它关闭与标准C流对象的同步:

std::ios_base::sync_with_stdio(false);
一旦你做到了这一点,你应该会有更好的表现。不过,你是否表现良好是另一个问题

由于一些人声称猫在里面会做些有趣的事情,下面是将一个流复制到另一个流的最快方法:

std::cout << std::cin.rdbuf();

我希望我最终能做到最好…

如果你真的想在stdin上有更好的性能,你应该尝试使用纯C

vector<char> line(0x1000);
while(!feof(stdin))
    fgets(&line.front(), line.size(), stdin);
矢量线(0x1000);
而(!feof(stdin))
fgets(&line.front(),line.size(),stdin);

<代码> > P>我认为更快的解决方案将基于

> <代码>筛选器范围。SH < /Cord>?为什么不直接调用C++程序?也就是说,该循环的典型模式是“代码>”(STD::GETLIN(STD:CIN,CRTLIN))。{std::cout如果你在寻找性能,你应该尝试C风格的I/O函数,而不是cin/cout;)你用优化编译了吗?-O2或-O3?这可能不会减少44秒,但如果你担心时间问题,那么肯定应该这样做。Rob:是的,你的版本是等效的,更漂亮。我用了它,调用了直接使用脚本,不做任何更改,我的程序不做任何其他事情。我使用的是g++-O3-Wall-c-fmessage length=0-MMD-mpd。您会惊讶地发现,您的通用命令比专门设计用于快速执行操作的专用工具慢。如果您编写的命令是beet cat,那么它将是新的cat。因为您正在执行行处理,所以期望您获得(在您进行大量优化之后)与任何基于行的unix筛选器的速度大致相同。我将此标记为答案,但也阅读了原始问题中的编辑。事实上,sync_with_stdio似乎非常有帮助。它将速度提高了7倍。实际上,这是一款黄金级的产品,因为它使cin的速度仅为fgets的2倍,另外一个好处是您不需要知道最大行长。…还有像这样的“优化”吗?:)没有,没有这么简单的了。我在某处有自己的IOStreams实现,它做了很多有趣的优化,但它的不完整状态现在对你没有帮助。不过,我仍然希望在某个时候得到它…;)
vector<char> line(0x1000);
while(!feof(stdin))
    fgets(&line.front(), line.size(), stdin);