Ram*_*ter 7 c++ performance cout
我注意到如果我使用cout打印出长字符串(char*),它似乎一次打印1个字符到Windows 7,Vista和Linux(使用putty)的屏幕上,使用Windows上的Visual C++ 2008和Linux上的G ++.Printf是如此快得多,我实际上从cout切换到printf,用于我的项目中的大多数打印.这让我感到困惑,因为这个问题让我觉得我是唯一一个有这个问题的人.
我甚至写了一个cout替换,看起来像是在我的comp上击败cout的裤子 -
class rcout
{
public:
char buff[4096];
unsigned int size;
unsigned int length;
rcout()
{
size = 4096;
length = 0;
buff[0] = '\0';
}
~rcout()
{
printf("%s", buff);
}
rcout &operator<<(char *b)
{
strncpy(buff+length, b, size-length);
unsigned int i = strlen(b);
if(i+length >= size)
{
buff[size-1] = '\0';
printf("%s", buff);
b += (size-length) -1;
length = 0;
return (*this) << b;
}
else
length += i;
return (*this);
}
rcout &operator<<(int i)
{
char b[32];
_itoa_s(i, b, 10);
return (*this)<<b;
}
rcout &operator<<(float f)
{
char b[32];
sprintf_s(b, 32, "%f", f);
return (*this)<<b;
}
};
int main()
{
char buff[65536];
memset(buff, 0, 65536);
for(int i=0;i<3000;i++)
buff[i] = rand()%26 + 'A';
rcout() << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
Sleep(1000);
cout << "\n\nOk, now cout....\n\n";
cout << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
Sleep(1000);
cout << "\n\nOk, now me again....\n\n";
rcout() << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
Sleep(1000);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
任何想法为什么cout打印这么慢对我来说?
min*_*ang 12
注意:此实验结果对MSVC有效.在库的其他一些实现中,结果会有所不同.
printf 可能(更快)比cout.虽然printf在运行时解析格式字符串,但它需要的函数调用要少得多,实际上需要少量指令才能完成相同的工作cout.以下是我的实验总结:
静态指令的数量
一般来说,cout生成很多代码printf.假设我们有以下cout代码用一些格式打印出来.
os << setw(width) << dec << "0x" << hex << addr << ": " << rtnname <<
": " << srccode << "(" << dec << lineno << ")" << endl;
Run Code Online (Sandbox Code Playgroud)
在具有优化的VC++编译器上,它生成大约188字节的代码.但是,当您替换printf基于它的代码时,只需要42个字节.
动态执行指令的数量
静态指令的数量只是告诉静态二进制代码的区别.更重要的是在运行时动态执行的实际指令数.我也做了一个简单的实验:
测试代码:
int a = 1999;
char b = 'a';
unsigned int c = 4200000000;
long long int d = 987654321098765;
long long unsigned int e = 1234567890123456789;
float f = 3123.4578f;
double g = 3.141592654;
void Test1()
{
cout
<< "a:" << a << “\n”
<< "a:" << setfill('0') << setw(8) << a << “\n”
<< "b:" << b << “\n”
<< "c:" << c << “\n”
<< "d:" << d << “\n”
<< "e:" << e << “\n”
<< "f:" << setprecision(6) << f << “\n”
<< "g:" << setprecision(10) << g << endl;
}
void Test2()
{
fprintf(stdout,
"a:%d\n"
"a:%08d\n"
"b:%c\n"
"c:%u\n"
"d:%I64d\n"
"e:%I64u\n"
"f:%.2f\n"
"g:%.9lf\n",
a, a, b, c, d, e, f, g);
fflush(stdout);
}
int main()
{
DWORD A, B;
DWORD start = GetTickCount();
for (int i = 0; i < 10000; ++i)
Test1();
A = GetTickCount() - start;
start = GetTickCount();
for (int i = 0; i < 10000; ++i)
Test2();
B = GetTickCount() - start;
cerr << A << endl;
cerr << B << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是Test1(cout)的结果:
那么,怎么样printf?这是Test2的结果:
在这台机器和编译器中,printf速度要快得多cout.在两个执行指令的数量和加载/存储的数量(表示缓存未命中数)中有3~4倍的差异.
我知道这是一个极端的例子.此外,我应该注意到,cout当您处理32/64位数据并且需要32/64平台独立性时,这会容易得多.总是有权衡.我cout在检查类型时使用非常棘手.
好的,cout在MSVS中糟透了:)
我建议你在另一台计算机上尝试相同的测试.对于为什么会发生这种情况,我没有一个好的答案; 我只能说我从来没有注意到cout和printf之间的速度差异.我还在Linux上使用gcc 4.3.2测试了你的代码,并没有任何区别.
话虽这么说,你不能轻易地用你自己的实现替换cout.事实上,cout是std :: ostream的一个实例,它内置了很多功能,这对于与iostream运算符重载的其他类的互操作性是必需的.
编辑:
任何人说printf总是快于std::cout根本就是错误的. 我刚刚运行了minjang发布的测试代码,gcc 4.3.2和64位AMD Athlon X2上的-O2标志,cout实际上更快.
我得到了以下结果:
printf: 00:00:12.024
cout: 00:00:04.144
Run Code Online (Sandbox Code Playgroud)
cout总是比printf快吗?可能不是.尤其不适用于较旧的实现.但是在较新的实现上,iostream可能比stdio更快,因为编译器在编译时不知道需要调用哪些函数才能将整数/浮点数/对象转换为字符串.
但更重要的是,printf与cout的速度取决于实现,因此OP描述的问题不容易解释.