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:
import sys
line_count = 0
input_line = ''
for line in sys.stdin:
input_line = line
line_count += 1#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!":
yes 'Hello, world!' | head -n 1000000 > dataEl resultado, con GCC 13.2 sobre un i3 de 4ta generación con Ubuntu porque soy pobre no tengo ganas de levantarme de la cama:
$ 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 millisAhora 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:
#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;
}$ 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 millisY así de fácil vamos de ~545ms a sólo ~59ms.
P.S. ya ves, @Lucien? C++ > Python. 😎