Огромная разница в скорости между одинаковыми программами c и c++
Я очень новичок в программировании на c и c++, поэтому я начну с основ. Я написал идентичные программы цикла Фибоначчи для c и c++ для проверки относительной скорости. Я думал, что они будут примерно одинаковыми для чего-то такого простого, но версия c++ медленнее в 60 раз. Все, что они делают, это перебирают и выводят первые 14 чисел Фибоначчи 10000 раз. Вот версия c:
#include <stdio.h>
int main (){
int c = 0;
int x, y, z;
while(c < 10000)
{
x = 0;
y = 1;
while(x < 255)
{
printf("%d\n", x);
z = x + y;
x = y;
y = z;
}
c++;
}
return 0;
}
а вот версия c++:
#include <iostream>
using namespace std;
int main()
{
int c = 0, x = 0, y = 0, z = 0;
while(c < 10000)
{
x = 0;
y = 1;
while(x < 255)
{
cout << x << endl;
z = x + y;
x = y;
y = z;
}
c++;
}
return 0;
}
Я написал оба в notepad++ и скомпилировал их, используя g++ из mingw, который поставляется с кодовыми блоками:
g++ -o fibc.exe fib.c -s
g++ -o fibcpp.exe fib.cpp -s
Размер исполняемых файлов очень разный: размер c равен 8,5 КБ, а размер c++ равен 784 КБ! Я использовал PowerShell для определения времени их:
Measure-Command {start-process "C:\Path\fibcpp.exe" -RedirectStandardOutput "C:\Path\cpp.txt" -Wait}
Полученные файлы идентичны, но версия c заняла 1 секунду, а версия c++ - 60 секунд! (На самом деле, создание цикла в 1 миллион для программы c заняло всего 13 секунд). Я также написал c++ в Visual Studio 17 и скомпилировал его с конфигурацией выпуска x86. Размер программы теперь составляет 9,5 КБ, но время выполнения совпадает с версией g++: 62 секунды. Почему это происходит для такой простой программы?
Ответы
Ответ 1
Вы сравниваете printf
с cout
, так как это основные узкие места в вашей программе.
printf
является ужасно медленной функцией, но, вероятно, все же быстрее, чем osteam
, который должен будет поддерживать свой собственный адский шаблон метапрограммирования, чтобы сохранить его настолько гибким, насколько этого требует стандарт C++. cout
определенно гораздо более гибкий и сложный, чем printf
. Дополнительные функции означают более медленный код.
Если вы действительно хотите сравнить два языка, удалите функции печати и замените их фиктивной функцией "foo" с внешней связью:
void foo (int x);
...
while(x < 255)
{
foo(x);
При сравнении этого кода с gcc -O3 для x86 я получаю практически идентичный код для версии C и C++ версии.
Единственное заметное отличие - это "CRT" goo, который C++ добавил в конце main(). Это вызов atexit и другой очистки, которую C тоже сделает, но, возможно, за пределами кода приложения. Тем не менее, в C++ всегда будут накладные расходы, поскольку он должен вызывать конструкции и очищать деструкторы объектов со статической продолжительностью хранения. С не должен этого делать.
Ответ 2
Причина, по которой C++ cout
работает медленно, объясняется в здесь.
По умолчанию объекты iostream и потоки cstdio синхронизируются (как если бы эта функция была вызвана с аргументом true в качестве аргумента).
Поэтому по умолчанию cout
синхронизируется со stdio.
Попробуйте выполнить следующее для ускорения.
ios_base::sync_with_stdio(false)
Но будьте осторожны, этот код напечатает то, чего вы не ожидаете.
#include <iostream>
#include <cstdio>
int main()
{
std::ios::sync_with_stdio(false);
std::cout << "a\n";
std::printf("b\n");
std::cout << "c\n";
}