- 970
- 1,985
A raíz de un video en YouTube (How To Scare C++ Programmer) que demuestra la "velocidad" de Python frente a la de C++ y porque no tengo nada mejor que hacer este fin de semana, me han dado ganas de probarlo.
El código mostrado en el video:
La entrada consiste en un millón de "Hello, world!":
El resultado, con GCC 13.2 sobre un i3 de 4ta generación con Ubuntu porquesoy pobre no tengo ganas de levantarme de la cama:
Ahora el plot twist. Por defecto,
Y así de fácil vamos de ~545ms a sólo ~59ms.
P.S. ya ves, Lucien? C++ > Python.
El código mostrado en el video:
Python:
import sys
line_count = 0
input_line = ''
for line in sys.stdin:
input_line = line
line_count += 1
C++:
#include <iostream>
using namespace std;
int main() {
string input_line;
long line_count = 0; // el optimizador igual elimina esta variable pero
// está en el video, así que la dejo.
while (cin) {
getline(cin, input_line);
if (!cin.eof()) line_count++;
}
return 0;
}
La entrada consiste en un millón de "Hello, world!":
Bash:
yes 'Hello, world!' | head -n 1000000 > data
El resultado, con GCC 13.2 sobre un i3 de 4ta generación con Ubuntu porque
Código:
$ time python3 ./readtest.py < data
________________________________________________________
Executed in 347.63 millis fish external
usr time 331.65 millis 1.28 millis 330.37 millis
sys time 16.12 millis 0.00 millis 16.12 millis
$ make CXXFLAGS+='-O3 -Wall' readtest && time ./readtest < data
g++ -O3 -Wall readtest.cc -o readtest
________________________________________________________
Executed in 555.25 millis fish external
usr time 545.20 millis 385.00 micros 544.81 millis
sys time 8.07 millis 117.00 micros 7.95 millis
Ahora el plot twist. Por defecto,
std::cin
y std::cout
están sincronizados con stdin
y stdout
, respectivamente, con el fin de permitir al programador entremezclar la E/S de C con la de C++ de una manera más conveniente. Desafortunadamente, esto implica que las operaciones se realizan sin usar un búfer de por medio, por eso la lentitud al leer las líneas. Si lo usamos (véase std::ios_base::sync_with_stdio()), la cosa cambia por completo:
C++:
#include <iostream>
using namespace std;
int main() {
string input_line;
long line_count = 0;
ios_base::sync_with_stdio(false); // esta línea de aquí
while (cin) {
getline(cin, input_line);
if (!cin.eof()) line_count++;
}
return 0;
}
Código:
$ make CXXFLAGS+='-O3 -Wall' readtest && time ./readtest < data
g++ -O3 -Wall readtest.cc -o readtest
________________________________________________________
Executed in 74.90 millis fish external
usr time 59.18 millis 466.00 micros 58.71 millis
sys time 15.80 millis 147.00 micros 15.66 millis
P.S. ya ves, Lucien? C++ > Python.