Por qué debemos evitar usar std::endl

Es una práctica común usar std::endl para imprimir líneas nuevas mientras se usa cout. Para programas pequeños con muy pocas operaciones de E/S, esta práctica es aceptable, pero si aumenta la mayor parte de las operaciones de E/S, la eficiencia del programa se verá comprometida.

std::endl no solo agrega nuevas líneas a la transmisión, sino que también vacía el búfer cada vez que se usa. Por lo tanto, cuando escribimos

 cout << std::endl 

En realidad estamos haciendo algo como esto.

 cout << '\n' << std::flush; 

El vaciado de búferes es una tarea del sistema operativo. Cada vez que se vacía el búfer, se debe realizar una solicitud al sistema operativo y estas requests son comparativamente costosas. Además, realmente no necesitamos vaciar el búfer cada vez que escribimos algo en la secuencia, ya que los búferes se vacían automáticamente cuando se llenan. En los raros casos en que necesitamos realizar un lavado, podemos especificar explícitamente la operación usando cout.flush() o insertando std::flush en la transmisión.

Escribir los caracteres ‘\n’ directamente en la transmisión es más eficiente ya que no fuerza un vaciado como std::endl.

Demostración del impacto en el rendimiento
El siguiente programa en C++ demuestra el impacto en el rendimiento de std::endl. Escribimos 100000 strings en dos archivos una vez usando std::endl y luego otra vez usando ‘\n’. En cada caso, medimos el tiempo de ejecución empleado e imprimimos estos tiempos

#include <iostream>
#include <chrono>
#include <fstream>
using namespace std;
using namespace std::chrono;
  
int main()
{
  ofstream file1("file1.txt");
  ofstream file2("file2.txt");
  
  
  // Write to file1 using endl 
  // To measure execution time in C++ 
  // refer to this article 
  // https://www.geeksforgeeks.org/measure-execution-time-function-cpp/  
  
  auto start = high_resolution_clock::now();
  for ( int i = 0; i < 100000; i++) {
    file1 << "Hello World " << std::endl ;
  }
  auto stop = high_resolution_clock::now();
  auto duration = duration_cast<microseconds>(stop-start);
  
  cout << "Writing to file using endl took "  
    << duration.count() << " microseconds" << std::endl;
  
  // Write to file2 using \n 
    
  start = high_resolution_clock::now();
  for ( int i = 0; i < 100000; i++) {
    file2 << "Hello World \n" ;
  }
  stop = high_resolution_clock::now();
  duration = duration_cast<microseconds>(stop-start);
  
  cout << "Writing to file using \\n took " 
    << duration.count() << " microseconds"<< std::endl;
  
  file1.close();
  file2.close();
  
  return 0;
}

Salida: (dependiente de la máquina)

Writing to file using endl took 3272 microseconds
Writing to file using \n took 1533 microseconds

Como se ve en la salida, std::endl tomó casi el doble de tiempo. En algunos sistemas, el impacto en el rendimiento podría ser aún peor. Tenga en cuenta que está garantizado que std::endl llevará más tiempo que imprimir ‘\n’ directamente en la transmisión.

Referencias:
C++ Weekly – Episodio 7

Publicación traducida automáticamente

Artículo escrito por Sayan Mahapatra y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *