2015-05-15 8 views
8

Ad esempio, ho due oggetti stringa: string str_1, str_2. Voglio concatenare loro. Posso utilizzare due metodi: Metodo 1:Stringstream è migliore dell'operatore stringa '+' per la concatenazione di oggetti stringa?

std::stringstream ss; 
//std::string str_1("hello"); 
//std::string str_2("world"); 
ss << "hello"<< "world"; 
const std::string dst_str = std::move(ss.str()); 

Metodo 2:

std::string str_1("hello"); 
std::string str_2("world"); 
const std::string dst_str = str_1 + str_2; 

A causa del buffer della stringa è di sola lettura, quando si cambia l'oggetto stringa, il suo buffer distruggerà e creare un nuovo uno per memorizzare nuovi contenuti. Quindi il metodo 1 è migliore del metodo 2? La mia comprensione è corretta?

+2

La risposta è ovvia (vale a dire, il metodo # 2). Si evita la creazione di un 'stringstream' oltre ai due inserimenti più la chiamata a' .str() '. – 101010

+4

@cwfighter Hai provato a profilare le due opzioni? –

+3

C++! = C# o Java. Le stringhe C++ non sono immutabili. – dandan78

risposta

8

stringstreams sono oggetti complessi rispetto alle stringhe semplici. Ogni volta che usi il metodo 1, deve essere costruito un stringstream e successivamente distrutto. Se lo fai milioni di volte, il sovraccarico sarà tutt'altro che trascurabile.

L'apparentemente semplice ss << str_1 << str_2 è infatti equivalente a std::operator<<(sst::operator<<(ss, str_1), str_2); che non è ottimizzato per la concatenazione di memoria, ma comune a tutti gli streams.

Ho fatto un piccolo punto di riferimento:

  • in modalità debug, il metodo 2 è quasi due volte più veloce Method1.

  • Nella build ottimizzata (verificando nel file assembler che nulla è stato ottimizzato), è più di 27 volte più veloce.

+0

Grazie per l'aiuto. Il mio test è uguale alla tua risposta. – cwfighter

0
  • Il metodo 2 è migliore come la tua situazione qui. Dal momento che ha una migliore leggibilità e tempo costano meno per declinare la creazione di oggetti stringstream.
  • Tuttavia, consiglio vivamente di utilizzare il formato per una migliore leggibilità & di manutenzione, anziché "+" o altra concatenazione di stringhe.
0

Thans per tutti. Forse ero un po 'pigro. Ora ho dato il test del codice.

test 1: 158.751ms, così a lungo, mio ​​dio!

int main() 
    { 
     chrono::high_resolution_clock::time_point begin_time = chrono::high_resolution_clock::now(); 
     for(int i=0;i<100000;i++) 
     { 
      //string str_1("hello "); 
      //string str_2("world"); 
      stringstream ss; 
      ss << "hello " << "world"; 
      const string dst_str = ss.str(); 
     } 
     chrono:: high_resolution_clock::time_point stop_time = chrono::high_resolution_clock::now(); 

     chrono::duration<double> slapsed = duration_cast<duration<double>>(stop_time - begin_time); 
     cout << "time takes " << slapsed.count() * 1000 << "ms" << endl; 
     return 0; 
    } 

test 2: 31.1946ms, più veloce!

int main() 
    { 
     chrono::high_resolution_clock::time_point begin_time = chrono::high_resolution_clock::now(); 
     for(int i=0;i<100000;i++) 
     { 
      string str_1("hello "); 
      string str_2("world"); 
      const string dst_str = str_1 + str_2; 
     } 
     chrono:: high_resolution_clock::time_point stop_time = chrono::high_resolution_clock::now(); 

     chrono::duration<double> slapsed = duration_cast<duration<double>>(stop_time - begin_time); 
     cout << "time takes " << slapsed.count() * 1000 << "ms" << endl; 
     return 0; 
    } 

test 3: uso boost :: 35.1769ms filesystem :: percorso, anche una buona scelta

int main() 
    { 
     chrono::high_resolution_clock::time_point begin_time = chrono::high_resolution_clock::now(); 
     for(int i=0;i<100000;i++) 
     { 
      string str_1("hello "); 
      string str_2("world"); 
      boost::filesystem::path dst_path(str_1); 
      dst_path += str_2; 
      const string dst = dst_path.string(); 
     } 
     chrono::high_resolution_clock::time_point stop_time = chrono::high_resolution_clock::now(); 

     chrono::duration<double> slapsed = duration_cast<duration<double>>(stop_time - begin_time); 
     cout << "time takes " << slapsed.count() * 1000 << "ms" << endl; 
     return 0; 
    } 
Problemi correlati