2011-06-14 15 views
7

En C++, que sería más rápido si se repite, por ejemplo, 5000 veces:impresión a la consola frente a la escritura en un archivo (velocidad)

cout << "text!" << endl; 

o

my_text_file << "text!" << endl; 

(escribir en un archivo vs cout-ción a la consola)

Editar:

lo pregunto porque cuando se escribe en la consola, ver todo el texto siendo pri nted que parece que ralentizaría el ciclo. En un archivo, no se ve el texto que se está imprimiendo, lo que parece que tomaría menos tiempo.

acabo de probar que:

consola:> 2000 ms utilizando endl y \ n

del archivo: 40 ms con endl y 4 ms con \ n

+1

¿Por qué no lo pruebas? – Duck

+0

No puede asegurarse de cuál es la salida estándar a la que se redirige, pero el acceso al disco (como escribir en un archivo) es _mucho_ más lento que el acceso de ram (consola de impresión). – JulioC

+4

@Julio: ¿Has probado esto en un entorno real alguna vez? Imprimir a la consola suele ser mucho más lento que escribir en el disco, no solo deja los caracteres en un búfer, sino que el búfer es limitado y el contenido de ese búfer debe moverse a la tarjeta de video (un terminal de texto real) o dibujado en la pantalla (un terminal gráfico) con suficientes datos, el buffer intermedio se llena, y el proceso del escritor se queda en espera de que se dibuje la salida ... Antes de hacer este tipo de declaraciones * strong * sobre el rendimiento, mida realmente, en una entorno real con datos suficientes lo verá usted mismo. –

Respuesta

12

Escribir en un archivo sería mucho más rápido. Esto es especialmente cierto ya que está descargando el búfer después de cada línea con endl.

En una nota lateral, puede acelerar la impresión de manera significativa repitiendo cout << "text!\n"; 5000 veces, luego vaciar el búfer con flush().

+4

Esto probablemente suene tonto ... ¿Qué es exactamente el buffer? – Christian

+2

Cuando imprime algo en una secuencia (como cout), todo lo que envía se almacena en un búfer antes de que se coloque allí (enjuagado). Ocurre de vez en cuando, y cuando la ejecución del programa se completa correctamente. Sin embargo, usar flush o endl lo vacía explícitamente. Esto solo garantiza que las cosas se impriman cuando lo deseamos. –

1

escribir la misma cantidad de datos, con el mismo tamaño de búfer para la consola definitivamente será más rápido que escribir en un archivo.

Puede acelerar su velocidad de escritura (tanto para la salida de la consola como para el archivo) al no escribir el búfer con cada línea (es decir, no use std :: endl después de cada línea, ya que ambas línea final a la secuencia, y escribe el buffer). En su lugar, use "\ n" a menos que deba asegurarse de que el búfer se emita por algún motivo.

+0

A menos que esté produciendo a través de un enlace en serie muy lento. – genpfault

+1

¿Incluyendo toda la impresión y el desplazamiento que serían visibles al imprimir en la consola? En un archivo de texto, no verá el texto escrito. – Christian

+0

Escribir en la consola es más rápido, pero si la operación de escritura es todo lo que se realiza, entonces un programa que escriba en un archivo probablemente termine primero. – jswolf19

0

No es que mucho más rápido ...

una prueba de 1 million couts con endl (tampón claro):

Resultados:

console cout time: 2.87001 
file cout time: 2.33776 

Código:

class Timer 
{ 
     struct timespec startTime, endTime; 
     double sec; 
public: 
     void start(); 
     void stop(); 
     double getSec(); 
}; 

void Timer::start() 
{ 
     clock_gettime(CLOCK_MONOTONIC, &startTime); 
} 
void Timer::stop() 
{ 
     clock_gettime(CLOCK_MONOTONIC, &endTime); 
     sec = (endTime.tv_sec - startTime.tv_sec); 
     sec += (endTime.tv_nsec - startTime.tv_nsec)/1000000000.0; 
} 
double Timer::getSec() 
{ 
     return sec; 
} 


int main(){ 
     int ntests = 1000000; 
     Timer t1 = Timer(), t2 = Timer(); 

     t1.start(); 
     for(int c=0;c<ntests;c++) 
     { 
       cout << "0" << endl; 
     } 
     t1.stop(); 

     ofstream out("out.txt"); 
     streambuf *coutbuf = cout.rdbuf(); 
     cout.rdbuf(out.rdbuf()); 
     t2.start(); 
     for(int c=0;c<ntests;c++) 
     { 
       cout << "0" << endl; 
     } 
     t2.stop(); 
     cout.rdbuf(coutbuf); 

     cout << "console cout time: " << t1.getSec() << endl; 
     cout << "file cout time: " << t2.getSec() << endl; 
} 

Build y ejecutar:

g++ test.cpp -o test -lrt && ./test && rm out.txt 
0

Además de que la E/S de consola generalmente es relativamente lenta, la configuración predeterminada de las transmisiones estándar cout y cin tiene algunos problemas que ralentizarán en gran medida el rendimiento si no se corrigen.

La razón es que los mandatos estándar que, por defecto, cout y cin de la biblioteca de C++ iostream deben trabajar junto stdout y stdin de la biblioteca de la C stdio de la forma esperada.

Esto significa básicamente que cout y cin no puede hacer ningún buffering en absoluto en sus internos streambuf s y, básicamente, reenvía todas las operaciones de E/S a la biblioteca C.

Si usted quiere hacer algo parecido a un alto rendimiento de E/S con los flujos estándares, es necesario desactivar esta sincronización con

std::ios_base::sync_with_stdio(false); 

antes de realizar cualquier E/S.

Cuestiones relacionadas