2015-06-21 18 views
6

Stavo sperimentando con C++ cercando di capire come stampare i numeri da 0 a n il più velocemente possibile.Come posso stampare una nuova riga senza svuotare il buffer?

Inizialmente ho appena stampati tutti i numeri con un ciclo:

for (int i = 0; i < n; i++) 
{ 
    std::cout << i << std::endl; 
} 

Ritengo tuttavia questo svuota il buffer dopo ogni singolo numero che emetta, e sicuramente che deve richiedere un certo tempo, così ho provato per prima cosa stampare tutti i numeri sul buffer (o in realtà fino a quando non è pieno come sembra, quindi sembra che si svuotino automaticamente) e poi scarichi tutto in una volta. Tuttavia sembra che la stampa di un \ n dopo vampate di buffer come lo std :: endl così ho omesso che:

for (int i = 0; i < n; i++) 
{ 
    std::cout << i << ' '; 
} 
std::cout << std::endl; 

Questo sembra funzionare circa 10 volte più veloce rispetto al primo esempio. Tuttavia voglio sapere come memorizzare tutti i valori nel buffer e lavare tutto in una volta, piuttosto che lasciare a filo ogni volta che si riempie quindi ho alcune domande:

  1. E 'possibile stampare una nuova riga senza sciacquare il buffer?
  2. Come posso modificare la dimensione del buffer in modo da poter memorizzare tutti i valori al suo interno e svuotarla alla fine?
  3. Questo metodo di emissione di testo è stupido? Se è così, perché, e quale sarebbe un'alternativa migliore ad esso?

EDIT: Sembra che i miei risultati sono stati influenzati da un sistema di lag (app Terminal di uno smartphone) ... Con un sistema più veloce i tempi di esecuzione non mostrano differenze significative.

+0

Provare a deselezionare [unitbuf] (http://en.cppreference.com/w/cpp/io/manip/unitbuf) flag su 'cout' prima di scrivere. –

+3

Non usare 'endl' perché forza lo svuotamento, ecc. Usa' '\ n'' o' "\ n" 'invece? Oppure puoi entrare in trucchi più elaborati impostando la modalità di buffering di 'std :: cout' completamente bufferizzata. –

+0

'std :: cout << '\ n'' stampa una nuova riga. Non svuotare manualmente a meno che non si abbia un motivo per farlo. – nwp

risposta

3

TL; DR: In generale, utilizzando '\n' invece di std::endl è più veloce in quanto std::endl

Spiegazione: std::endl causa un rossore del buffer, mentre '\n' non lo fa. Tuttavia, potresti o non potresti notare alcun tipo di accelerazione a seconda del metodo di test che applichi.

Si consideri il seguente file di prova:

endl.cpp:

#include <iostream> 

int main() { 
    for (int i = 0 ; i < 1000000 ; i++) { 
     std::cout << i << std::endl; 
    } 
} 

slashn.cpp:

#include <iostream> 

int main() { 
    for (int i = 0 ; i < 1000000 ; i++) { 
     std::cout << i << '\n'; 
    } 
} 

Entrambi questi sono compilati utilizzando g++ sul mio linux sistema e sottoposto alle seguenti prove:

1. time ./a.out

Per endl.cpp, ci vuole 19.415s.
Per slashn.cpp ci vogliono 19,312 secondi.

2.time ./a.out >/dev/null

Per endl.cpp, richiede 0.397s
Per slashn.cpp, richiede 0.153s

3. time ./a.out >temp

Per endl.cpp, richiede 2.255s
Per slashn.cpp ci vogliono 0,165s

Conclusione:'\n' è decisamente più veloce (anche praticamente), ma la differenza di velocità può dipendere da altri fattori. Nel caso di una finestra terminale, il fattore limitante sembra dipendere dalla velocità con cui il terminale stesso può visualizzare il testo. Poiché il testo viene visualizzato sullo schermo, e lo scorrimento automatico deve essere eseguito, si verificano massicci rallentamenti nell'esecuzione. D'altra parte, per i file normali (come l'esempio temp sopra), la velocità con cui viene scaricato il buffer lo influenza molto. Nel caso di alcuni file speciali (come /dev/null sopra), dato che i dati sono semplicemente affondati in un buco nero, il flushing non sembra avere un effetto.

Problemi correlati