ПРИМЕЧАНИЕ : Этот экспериментальный результат действителен для MSVC. В некоторых других реализациях библиотеки результат будет другим.
printf
может быть (намного) быстрее, чем cout
. Хотя printf
анализирует строку формата во время выполнения, для этого требуется гораздо меньше вызовов функций и фактически требуется небольшое количество инструкций для выполнения той же работы по сравнению с cout
. Вот краткое изложение моих экспериментов:
Номер статической инструкции
Как правило, cout
генерирует больше кода, чем printf
. Скажем, у нас есть следующий cout
код для печати в некоторых форматах.
os << setw(width) << dec << "0x" << hex << addr << ": " << rtnname <<
": " << srccode << "(" << dec << lineno << ")" << endl;
В компиляторе 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;
}
Вот результат Test1 (cout):
выполненной инструкции: 423 234 439
памяти загружается / хранится: прибл. 320 000 и 980 000
- Истекшее время: 52 секунд
Тогда как насчет printf
? Это результат Test2:
выполненной инструкции: 164 800 800
памяти загружается / хранится: прибл. 70 000 и 180 000
- Истекшее время: 13 секунд
В этой машине и компиляторе printf
был намного быстрее cout
. Как в количестве выполненных инструкций, так и в количестве загрузок / хранилищ (указывает на количество пропущенных кешей) разница в 3 ~ 4 раза.
Я знаю, что это крайний случай. Также следует отметить, что cout
намного проще, когда вы обрабатываете 32/64-битные данные и вам требуется независимость от 32/64-платформ. Всегда есть компромисс. Я использую cout
при проверке типа очень сложно.
Хорошо, cout
в MSVS просто отстой :)