2012-03-11 17 views
9

Eventuali duplicati:
C++: “std::endl” vs “\n”Buffer vampate di calore: " n" vs. std :: endl

In Accelerated C++, due cose sono menzionati:

  1. La maggior parte dei sistemi richiede molto tempo per scrivere i caratteri su un dispositivo di output. Per questo motivo, C++ accumula caratteri da scrivere in un buffer e attende che il buffer venga svuotato.

  2. Un modo per il quale un buffer può essere svuotato è se gli si dice esplicitamente di farlo utilizzando std::endl.

Questo mi ha fatto pensare: Ovviamente i benefici sarebbero molto piccola e impercettibile per tutto tranne la più grande delle uscite, ma sta usando "\n" più veloce rispetto all'utilizzo std::endl, o fa "\n" svuotare anche un buffer?

+3

Hai provato a misurarlo? –

+1

Sì, questo è un dettaglio di implementazione, quindi non otterrai una risposta definitiva. La mia ipotesi è che faccia la differenza nella maggior parte delle implementazioni, ma questo non deve essere vero. –

+0

@Carl - Certo, non l'ho fatto, non saprei nemmeno come. Stavo leggendo il libro ed ero curioso, quindi ho pensato di chiederlo. –

risposta

8

L'uso di \ n non svuota il buffer ed è effettivamente più veloce rispetto all'utilizzo di std :: endl.

Nell'I/O tipico, l'output viene memorizzato nel buffer prima di essere scritto nel dispositivo desiderato. In questo modo, quando si scrive per rallentare l'accesso ai dispositivi (come i file), non è necessario accedere al dispositivo dopo ogni singolo carattere. Flushing "scarica" ​​il buffer sul dispositivo, causando un overhead delle prestazioni definito.

-Adapted da: C++ - endl and flushing the buffer

+1

Per alcuni [in genere] un valore molto piccolo di "più veloce" ;-) –

+2

@pst: beh, quando si invia una grande quantità di dati al file può effettivamente uccidere le prestazioni (mi è successo una volta quando scrivevo alcune decine di MB di dati in CSV). –

+0

@MatteoItalia Vero, non stavo pensando all'inverso :( –

0

vorrei aggiungere che ritengo intenzione di scrivere '\n' al flusso potrebbe essere diverso da scrivere std::endl/std::flush in librerie di terze parti.

Ad esempio, sto utilizzando il logger basato su ostream nel progetto corrente. Questo logger utilizza la funzionalità std::stringstream per la formattazione dell'output, ma ha manipolatori sovrascritti per il flushing. Ciò consente di scrivere '\n' nel log senza eseguire il flushing e semplifica il codice.

Ecco un esempio pseudocodice:

class MyStream 
{ 
    // [cut] 
    std::stringstream m_buffer; 
    // [cut] 
}; 

// friends: 
template <typename Printable> 
MyStream& operator<<(MyStream& stream, const Printable& value) 
{ 
    stream.m_buffer << value; 
} 

typedef decltype(std::flush) TManipulator; 
template <> 
MyStream& operator<<(MyStream& stream, const TManipulator& manipulator) 
{ 
    if (manipulator == std::flush || manipulator == std::endl) 
     stream.sendLogLine(); 
    else 
     stream.m_buffer << manipulator; 
} 

// usage sample 
void main() 
{ 
    getLoggerStream() << "hello" << std::endl; 
} 

P.S. Non mi piaceva sottoclasse std::stringstream, quindi MyStream è un adattatore. Se voglio effettuare lo svuotamento '\n', dovrei reimplementare molte più funzionalità tra cui char*, std::string e altre specializzazioni.

Problemi correlati