Introduction : la guerre des deux symboles
Si vous avez déjà programmé en C++ et affiché du texte dans la console, vous avez forcément été confronté au dilemme : utiliser std::endl ou "" ? À première vue, la différence est minime — les deux passent à la ligne. Mais derrière ce choix simple se cache toute une histoire de performances, de mise en tampon et de ralentissements inattendus dans votre programme.
Sur Stack Overflow, cette question a recueilli des milliers de vues et a suscité des débats animés. Aujourd'hui, nous allons analyser ce sujet une fois pour toutes : lequel est le plus rapide, pourquoi et quand chaque option est justifiée. Si vous programmez en C++ et souhaitez que votre code soit le plus efficace possible, cet article est pour vous.
Réponse courte (spoiler)
"" est toujours plus rapide que std::endl. Mais pas parce que std::endl est lent en lui-même, mais parce qu'il fait un travail supplémentaire. std::endl ne se contente pas d'ajouter un caractère de nouvelle ligne — il vide également le tampon de sortie (flush). Et c'est une opération qui peut vous coûter de précieuses millisecondes.
Voyons ce que cela signifie en pratique, et examinons le code.
Comment fonctionne la sortie en C++
Lorsque vous écrivez std::cout << "Bonjour";, les données ne sont pas envoyées immédiatement à l'écran. Elles s'accumulent dans un tampon — un stockage temporaire en mémoire. Cela est fait pour des raisons d'efficacité : envoyer les données caractère par caractère à l'écran est trop lent, le système attend donc d'avoir suffisamment de données pour les envoyer en un seul paquet.
Le vidage du tampon (flush) est l'envoi forcé de toutes les données accumulées. C'est exactement ce que fait std::endl.
Que se passe-t-il sous le capot ?
// Utilisation de std::endlstd::cout << "Ligne 1" << std::endl;// Équivalent à :std::cout << "Ligne 1" << '' << std::flush;
// Utilisation de ""std::cout << "Ligne 1";// Ajoute simplement un caractère de nouvelle ligne dans le tamponVous voyez la différence ? std::endl effectue deux actions : ajouter '' et appeler std::flush. "" n'en fait qu'une.
Expérience : mesurons les performances
Vérifions cela avec un exemple concret. Écrivons un petit programme qui affiche 100 000 lignes de deux manières différentes et mesure le temps.
#include <iostream>#include <chrono>
int main() { const int N = 100000; // Test avec std::endl auto start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < N; ++i) { std::cout << "Ligne numéro " << i << std::endl; } auto end = std::chrono::high_resolution_clock::now(); auto duration_endl = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); std::cout << "Temps avec endl : " << duration_endl.count() << " ms"; // Test avec "" start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < N; ++i) { std::cout << "Ligne numéro " << i << ""; } end = std::chrono::high_resolution_clock::now(); auto duration_n = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); std::cout << "Temps avec \\ : " << duration_n.count() << " ms"; return 0;}Résultat (typique) :
std::endl: ~350-400 ms"": ~5-10 ms
Une différence de 30 à 70 fois ! Et ce n'est pas une blague. Chaque appel à std::endl force le système à interagir avec le système d'exploitation pour vider le tampon. Et c'est un appel système, qui est relativement coûteux.
Quand le flush est-il nécessaire ?
Mais ne vous précipitez pas pour abandonner complètement std::endl. Parfois, le vidage du tampon est critique